Когда создается экземпляр класса, для каждой функции в определении класса экземпляр будет иметь в своем каталоге атрибут с тем же именем, что и у функции. Этот «атрибут функции», предполагая, что функция является либо методом класса, либо методом экземпляра / привязки, будет иметь в качестве значения другой каталог, который включает все атрибуты, найденные в объектах функции, в дополнение к __func__
и __self__
. __func__
содержит еще один каталог - каталог функции, найденный в самом классе - который, конечно, содержит все атрибуты, найденные в объектах функции (например, все атрибуты в __func__
указывают на тот же объект, что и атрибуты с одинаковыми именами в класс 'функциональный каталог). Предположительно, атрибуты в каталоге функций экземпляра отождествляются с идентичным атрибутом, найденным в каталоге __func__
, когда функция вызывается из экземпляра (и когда функция вызывается из экземпляра, атрибут __call__
метода экземпляра откладывает до __func__.__call__
). Почему же тогда экземпляры создают этот атрибут __func__
? Почему бы не сделать так, чтобы атрибуты каталога функции непосредственного экземпляра указывали прямо на атрибуты каталога функции класса так же, как работают методы stati c? Кажется, что экземпляры используют больше памяти, чем им нужно.
Чтобы сделать это несоответствие более ясным:
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__
), не ссылаются на один и тот же объект, но, по-видимому, они вызывают этот объект. Почему go из-за проблем с воссозданием этих атрибутов за пределами __func__
просто для вызова их в __func__
? Почему бы не сбросить атрибуты в __func__
в dir (s.maxArea), а атрибут __self__
express сообщит, что метод должен быть вызван как метод экземпляра?