상위 목록: 하위 목록: 작성 날짜: 읽는 데 23 분 소요

속성(Attribute)

속성(Attribute)은 클래스 내부에 포함돼 있는 메서드변수를 의미합니다.

Python에서 속성(Attribute)은 크게 클래스 속성인스턴스 속성으로 나뉩니다.

클래스 속성은 클래스 내부의 메서드 단계와 동일한 영역에 위치한 변수를 의미합니다.

클래스 속성에 접근할 경우, 모든 클래스에 동일하게 영향을 미칩니다.

인스턴스 속성self를 통해 할당된 인스턴스만의 변수를 의미합니다.

주로, __init__이나 메서드 내부에서 할당된 변수를 의미합니다.

  • Tip : self자기자신을 의미합니다. 즉, 인스턴스를 지칭합니다.



클래스 속성과 인스턴스 속성 정의

class 클래스명:
    클래스 속성 = 

    def __init__(self, *args, *kwargs):
        self.인스턴스 속성 = 

    ...


클래스 속성

클래스 속성은 메서드와 동일 단계에 작성하게 됩니다.

self를 사용하지 않고 정의합니다. 그러므로 모든 클래스에 동일하게 영향을 미칩니다.

인스턴스가 생성될 때 초기화되지 않으므로, 클래스명.클래스 속성으로 참조가 가능합니다.


인스턴스 속성

인스턴스 속성은 인스턴스를 초기화할 때 생성됩니다.

self를 사용해 정의합니다. 그러므로 인스턴스 내에서만 영향을 미칩니다.

인스턴스가 생성될 때나 생성된 후 할당되므로, 인스턴스명.인스턴스 속성으로 참조가 가능합니다.


class Daeheeyun:

    class_value = 0

    def __init__(self):
        self.instance_value = 0

    def set_class_value(self):
        Daeheeyun.class_value = 10

    def set_instance_value(self):
        self.class_value = 20


instance1 = Daeheeyun()
instance2 = Daeheeyun()

print("--클래스 속성 변경--")
instance1.set_class_value()
print(instance1.class_value, instance2.class_value)

print("--인스턴스 속성 변경--")
instance1.set_instance_value()
print(instance1.class_value, instance2.class_value)

print("--속성(Attribute) 출력--")
print(instance1.__dict__)
print(instance2.__dict__)
결과
–클래스 속성 변경–
10 10
–인스턴스 속성 변경–
20 10
–속성(Attribute) 출력–
{‘instance_value’: 0, ‘class_value’: 20}
{‘instance_value’: 0}


Daeheeyun 클래스

instance1instance2를 생성해 instance1에 대해서만 작업을 진행합니다.

set_class_value 메서드는 클래스 속성을 변경하는 메서드입니다.

set_instance_value 메서드는 인스턴스 속성을 변경하는 메서드입니다.


set_class_value 메서드

instance1클래스 값을 변경하면, Daeheeyun에 대한 동일한 속성이 일괄 변경됩니다.

즉, instance2을 변경하지 않아도 클래스 자체의 값이 변경되어 instance2의 값도 변경됩니다.


set_instance_value 메서드

instance1인스턴스 값을 변경하면, instance1에 대한 속성만 변경됩니다.

메서드 내부에서 class_value를 인스턴스화합니다. 즉, instance2는 영향을 미치지 않습니다.


__dict__ 속성

__dict__는 현재 인스턴스에 할당된 인스턴스 속성만 출력합니다.

instance1의 인스턴스 속성은 instance_value와 인스턴스화 된 class_value입니다.

instance2의 인스턴스 속성은 instance_value입니다.

instance2에서 set_instance_value 메서드를 통해 class_value를 인스턴스화 하지 않아, 클래스 속성이 유지되기 때문입니다.



매직 메서드(Magic Method)

클래스의 속성을 사용할 때, 속성을 관리하는 메서드를 통해 속성이 정의되거나 할당됩니다.

이 메서드들을 통해 속성을 관리할 수 있습니다. 속성을 관리하는 매직 메서드를 재정의해 속성을 관리합니다.


__getattr__ : 존재하지 않는 속성 호출

class Daeheeyun:
    def __init__(self):
        self.value = 0

    def __getattr__(self, name):
        return name + "은 존재하지 않습니다."


instance = Daeheeyun()
print(instance.value)
print(instance.nothing)
결과
0
nothing은 존재하지 않습니다.

존재하지 않는 속성을 참조한다면, 일반적으로 AttributeError가 발생합니다.

하지만, __getattr__ 메서드를 정의한다면 존재하지 않는 속성을 호출할 때, __getattr__ 메서드가 실행됩니다.

이를 통해 오류를 발생시키지 않고, 속성을 새로 정의하거나 무시할 수 있습니다.

__getattr__ 메서드는 인스턴스의 다른 속성에 접근 할 수 없습니다.


__getattribute__ : 속성 호출

class Daeheeyun:
    def __init__(self):
        self.value = 0

    def __getattribute__(self, name):
        try:
            return super().__getattribute__(name)

        except AttributeError:
            value = "Empty"
            setattr(self, name, value)
            return value


instance = Daeheeyun()
print(instance.value)
print(instance.nothing)
결과
0
Empty

속성을 호출한다면, __getattribute__ 메서드가 실행됩니다.

어떠한 속성이나 메서드를 호출한다면 __getattribute__ 메서드를 거치게 됩니다.

__getattr__ 메서드는 존재하지 않는 속성만 호출되지만, __getattribute__는 모든 속성이 호출됩니다.

__getattribute__ 메서드를 재정의했다면, __getattr__는 호출되지 않습니다.

존재하지 않는 속성을 호출했다면, __getattribute__ 내부에서 AttributeError가 발생합니다.

  • Tip : getattr() 함수를 통해 __getattribute__를 호출할 수 있습니다. getattr(instance, "value")와 같이 사용합니다.

  • Tip : setattr() 함수는 속성을 정의하는 함수입니다. setattr(instance, name, value)와 같이 사용합니다.


__setattr__ : 속성 할당

class Daeheeyun:
    def __init__(self):
        self.value = 0

    def __setattr__(self, name, value):
        return super().__setattr__(name, value * 2)


instance = Daeheeyun()
instance.value = 10
instance.nothing = 30
print(instance.value)
print(instance.nothing)
결과
20
60

속성을 변경하거나 할당한다면 __setattr__을 통해 값이 할당됩니다.

주의사항으로는 __setattr__ 내부에서 속성을 변경하거나 할당한다면, 다시 __setattr__가 실행됩니다.

그러므로, 재귀 되어 무한루프에 빠지게 됩니다.

__setattr__ 메서드 내부에서는 속성을 변경하거나 할당하지 않습니다.


__delattr__ : 속성 제거

class Daeheeyun:
    def __init__(self):
        self.value = 0

    def __delattr__(self, name):
        print("제거 :", name)
        return super().__delattr__(name)


instance = Daeheeyun()
del instance.value
결과
제거 : value

속성을 제거하면 __delattr__가 호출됩니다.

del이나, delattr() 함수를 통해 속성을 제거할 때 실행됩니다.

return super().__delattr__(name) 방식 이외에도, return 없이 del self.__dict__[name]처럼 속성을 제거할 수 있습니다.

  • Tip : delattr() 함수는 속성을 제거하는 함수입니다. delattr(instance, "value")와 같이 사용합니다.


__slots__ : 속성 제한, __dir__ : 속성 보기

class Daeheeyun:

    __slots__ = ["value"]

    def __init__(self):
        self.value = 0

    def __dir__(self):
        return sorted(super().__dir__(), key=str.upper)


instance = Daeheeyun()
print(instance.__slots__)
print(instance.__dir__())
결과
[‘value’]
[‘value’, ‘__class__’, ‘__delattr__’, ‘__dir__’, ‘__doc__’, ‘__eq__’, ‘__format__’, ‘__getattribute__’, ‘__ge__’, ‘__gt__’, ‘__hash__’, ‘__init_subclass__’, ‘__init__’, ‘__le__’, ‘__lt__’, ‘__module__’, ‘__new__’, ‘__ne__’, ‘__reduce_ex__’, ‘__reduce__’, ‘__repr__’, ‘__setattr__’, ‘__sizeof__’, ‘__slots__’, ‘__str__’, ‘__subclasshook__’]

__slots__은 클래스 내부에서 사용가능한 속성의 이름을 제한합니다.

즉, 사용할 속성(변수)의 이름을 미리 정의합니다. 다른 이름을 가진 속성명은 할당할 수 없습니다.

__slots__으로 속성이 제한되면, __dict__를 생성하지 않습니다.

__dir__은 클래스 내부에서 사용 가능한 모든 속성을 출력합니다.

dir(instance)를 통해서도 호출이 가능합니다.

댓글 남기기