请参阅下面的简单示例:
class Celsius(object):
def __init__(self, value=0.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
def __call__(self):
print('__call__ called')
class Temperature(object):
celsius = Celsius()
def __init__(self):
self.celsius1 = Celsius()
T = Temperature()
print('T.celsius:', T.celsius)
print('T.celsius1:', T.celsius1)
output
T.celsius: 0.0
T.celsius1: <__main__.Celsius object at 0x023544F0>
Run Code Online (Sandbox Code Playgroud)
我想知道为什么他们有不同的输出.我知道T.celsius会打电话给__get__并T.celsius1致电__call__.
不同之处在于第一个属性是类属性,而第二个属性是实例属性.
根据文档,如果至少实现第一个Descriptor方法(__get__,__set__和__delete__)的对象保存在类属性中,__get__则在访问时将调用其方法.实例属性不是这种情况.您可以从howto中了解更多信息.
__call__只有在函数调用对象时,对象的方法才会起作用:
>>> class Foo:
... def __call__(self):
... return "Hello there!"
...
>>> f = Foo()
>>> f()
'Hello There!'
Run Code Online (Sandbox Code Playgroud)
如果你尝试这样做,你会看到相同的结果。
print('T.celsius:', T.celsius)
print('T.celsius1:', T.celsius1.value)
Run Code Online (Sandbox Code Playgroud)