【发布时间】:2020-03-27 19:26:39
【问题描述】:
当一个类的实例被创建时,对于类定义中的每个函数,该实例的目录中都会有一个与函数同名的属性。这个“函数属性”,假设函数是类方法或实例/绑定方法,将有另一个目录作为其值,其中包括除__func__ 和__self__ 之外的函数对象中的所有属性。 __func__ 包含另一个目录——在类本身中找到的函数的目录——它当然包含在函数对象中找到的所有属性(例如,__func__ 中的所有属性与类的函数目录)。据推测,当从实例调用函数时,实例函数目录中的属性会延迟到在 __func__ 目录中找到的相同属性(并且当从实例调用函数时,实例的方法的 __call__ 属性会延迟到__func__.__call__)。那么为什么实例仍然创建这个__func__ 属性呢?为什么不让直接实例函数目录属性直接指向类函数目录属性,就像静态方法操作一样?似乎实例使用的内存超出了它们的需要。
为了更清楚地说明这种差异:
class Solution:
def maxArea(self, height):
pass
@staticmethod
def i_am_static():
pass
@classmethod
def i_am_a_class_method():
pass
s = Solution()
print("\n\nDirectory of Instance Method:")
print(dir(s.maxArea))
print("\n\nDirectory of Instance Method __func__ attribute:")
print(dir(s.maxArea.__func__))
print("\n\nEqualities:")
print("s.maxArea.__func__.__call__== Solution.maxArea.__call__? ",
s.maxArea.__func__.__call__ == Solution.maxArea.__call__)
print("s.maxArea.__call__ == Solution.maxArea.__call__? ",
s.maxArea.__call__ == Solution.maxArea.__call__)
print("\n\nDirectory of Static Method:")
print(dir(s.i_am_static))
print("\nInstance Method has these other methods:")
for i in dir(s.maxArea):
if i not in dir(s.i_am_static):
print(i)
print("\nStatic Method has these other methods:")
for i in dir(s.i_am_static):
if i not in dir(s.maxArea):
print(i)
打印:
Directory of Instance Method:
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__func__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Directory of Instance Method __func__ attribute:
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Equalities:
s.maxArea.__func__.__call__ == Solution.maxArea.__call__? True
s.maxArea.__call__ == Solution.maxArea.__call__? False
Directory of Static Method:
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Instance Method has these other methods:
__func__
__self__
Static Method has these other methods:
__annotations__
__closure__
__code__
__defaults__
__dict__
__globals__
__kwdefaults__
__module__
__name__
__qualname__
查看等式,我们可以看到__func__ 中的属性引用了类本身创建的同一个对象。但是,不在__func__ 中的属性(例如__call__)没有引用同一个对象,但它们可能调用了那个对象。为什么要麻烦在__func__ 之外重新创建这些属性,只是为了调用__func__ 中的那些?为什么不将__func__ 中的属性转储到dir(s.maxArea) 中,__self__ 属性会表示该方法应该作为实例方法调用?
【问题讨论】:
标签: python class directory attributes instance