Python 속성을 성공적으로 사용했지만 어떻게 작동하는지 모르겠습니다. 클래스 외부의 속성을 역 참조하면 property
다음 유형의 객체를 얻습니다 .
@property
def hello(): return "Hello, world!"
hello # <property object at 0x9870a8>
그러나 클래스에 속성을 넣으면 동작이 매우 다릅니다.
class Foo(object):
@property
def hello(self): return "Hello, world!"
Foo().hello # 'Hello, world!'
언 바운드 Foo.hello
가 여전히 property
객체 라는 것을 알았 으므로 클래스 인스턴스화가 마법을 수행해야하지만 그 마법은 무엇입니까?
답변
다른 사람들이 언급했듯이 설명 자라는 언어 기능을 사용합니다.
클래스를 통해 액세스 할 때 실제 속성 개체가 반환되는 이유 Foo.hello
는 속성이 __get__(self, instance, owner)
특수 메서드를 구현하는 방법에 있습니다.
- 설명자가 인스턴스 에서 액세스되면 해당 인스턴스가 적절한 인수로 전달되고 해당 인스턴스
owner
의 클래스 입니다. - 클래스를 통해 액세스하면
instance
None이고 만owner
전달됩니다.property
객체는이 반환을 인식합니다self
.
Descriptors howto 외에도 Language Guide의 Implementing Descriptors 및 Invoking Descriptors 문서를 참조하세요 .
답변
@properties가 제대로 작동하려면 클래스가 object 의 하위 클래스 여야 합니다 . 클래스가 객체 의 하위 클래스가 아닌 경우 처음으로 setter에 액세스하려고하면 실제로는 setter를 통해 액세스하는 대신 더 짧은 이름을 가진 새 속성을 만듭니다.
다음은 올바르게 작동 하지 않습니다 .
class C(): # <-- Notice that object is missing
def __init__(self):
self._x = None
@property
def x(self):
print 'getting value of x'
return self._x
@x.setter
def x(self, x):
print 'setting value of x'
self._x = x
>>> c = C()
>>> c.x = 1
>>> print c.x, c._x
1 0
다음은 올바르게 작동합니다.
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
print 'getting value of x'
return self._x
@x.setter
def x(self, x):
print 'setting value of x'
self._x = x
>>> c = C()
>>> c.x = 1
setting value of x
>>> print c.x, c._x
getting value of x
1 1
답변
속성은 설명자 이며 설명자는 클래스 인스턴스의 구성원 일 때 특별히 작동합니다. 간단히 말해a
타입의 인스턴스 A
와 A.foo
디스크립터는 다음이다 a.foo
동등하다 A.foo.__get__(a)
.