[python] 객체 관련 내장함수!

ceaseless·2022년 3월 12일

getattr()

getattr() 메서드는 특정한 객체로부터 특정 속성값을 반환한다.

The getattr() function returns the value of the specified attribute from the specified object.

즉, 인스턴스로 선언한 객체가 가진 속성값을 가져오는데, 기본적으로 클래스로 속성에 접근하는 방법은 객체에 "." 으로 접근하는 방법을 대신하는 메서드라 생각된다.

class Student:
    class_number = 1
    
    def __init__(self, name, number):
        self.name = name
        self.number = number

    def print_info(self):
        print(self.name, self.number)
>>> a_student = Student("Jack", "001")
>>> a_student.class_number, a_student.name, a_student.number
(1, 'Jack', '001')
>>> getattr(a_student, "class_number"), getattr(a_student, "name"), getattr(a_student, "number")
(1, 'Jack', '001')

그렇다면 "."으로 속성에 접근할 수 있는데, getattr()은 어떠한 상황에서 사용할 수 있을까?

함수의 독스트링을 확인해보자.

"getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't exist;
without it, an exception is raised in that case."

getattr.__doc__로 독스트링을 확인해보면, 첫번째 인자로 object를 받는다.
우리가 선언한 a_student가 되겠다. 그리고 두번째 인자로 name[, default]를 받는다.
즉, 속성명을 받고 속성명이 없을 시 default로 반환할 수 있게끔 작용해준다.
dictionary에서 get() 메서드를 사용하는 맥락과 비슷하다.

위에서 선언한 Student 클래스에는 phone_number 속성이 없다. 따라서 getattr()로 phone_number를 얻고자 한다면, AttributeError가 발생하게 된다.
생성한 인스턴스가 해당 속성을 가지고 있는지 유무를 모를 때, 사용할 수 있겠다.

>>> getattr(a_student, "phone_number")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-21e35f789648> in <module>
----> 1 getattr(a_student, "phone_number")

AttributeError: 'Student' object has no attribute 'phone_number'

이런 상항에서 getattr()에서 default값을 지정해주면 된다.

>>> getattr(a_student, "phone_number", "000-0000-0000")
'000-0000-0000'

setattr()

getattr() 메서드가 이미 생성된 속성을 가져오는 것이라면, setattr()은 해당 가져오는 것이 아닌 해당 객체에 속성을 추가하는 메서드이다.
구문에 대한 입력인자는, 위에서 기술한 getattr()과 동일하다.

마찬가지로 setattr.__doc__으로 살펴보면 아래와 같이 기술되어 있다.

"Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''"

setattr(x, "y", v)x.y = v 가 된다고 기술되어 있다.
간단한 예제로 알아보자. 위의 예시에 이어서 a_student 객체에 phone_number를 추가를 해보도록 해보자.

>>>setattr(a_student, "phone_number", "010-1234-5678")
>>>a_student.phone_number, getattr(a_student, "phone_number")
('010-1234-5678', '010-1234-5678')

위처럼 사용할 수 있다.

그렇다면, 이렇게 추가한 속성이 Student 클래스에도 영향을 줄까? 그렇지는 않다.

해당 인스턴스에서 생성한 속성이기 때문에, phone_number는 a_student 객체 안에서만 존재한다.

Student를 열어보면 phone_number는 존재하지 않는다. 하지만, a_student를 열어보게 되면 phone_number가 남아있다.

>>> Student.__dict__
mappingproxy({'__module__': '__main__',
              'class_number': 1,
              '__init__': <function __main__.Student.__init__(self, name, number)>,
              'print_info': <function __main__.Student.print_info(self)>,
              '__dict__': <attribute '__dict__' of 'Student' objects>,
              '__weakref__': <attribute '__weakref__' of 'Student' objects>,
              '__doc__': None})
>>> a_student.__dict__
{'name': 'Jack', 'number': '001', 'phone_number': '010-1234-5678'}

hasattr(), delattr()

다음은 hasattr()delattr() 두 메서드이다.

이제는 위에서 설명한 것을 이해하였다면, 두 메서드의 이름만 봐도 어떠한 기능을 하는지 알 수 있을 것이다.

hasattr()은 해당 속성이 있는지 여부를 확인할 수 있다. 결과 값으로는 boolean을 반환한다.

delattr()는 해당 속성을 인스턴스에서 삭제시키는 메서드이다.

추가 설명은 생략하고 바로 예제를 통해 확인해 보도록 하겠다.

>>>print(hasattr(a_student, "phone_number"), hasattr(a_student, "email"))
True False
>>>delattr(a_student, "phone_number")
>>>print(hasattr(a_student, "phone_number"))
False

hasattr()로 확인했을 때, 위에서 getattr()은 속성값의 유무에 따라 에러를 발생시켰지만, hasattr()은 boolean을 반환해준다.

또한 delattr()로 삭제하였을 때는, 다시 hasattr()은 False를 반환하여 해당 속성이 삭제된 것을 확인할 수 있다.

0개의 댓글