Python中实例方法目录中的_func__;属性的用途是什么?

Python中实例方法目录中的_func__;属性的用途是什么?,python,class,directory,attributes,instance,Python,Class,Directory,Attributes,Instance,创建类的实例时,对于类定义中的每个函数,该实例的目录中将有一个与该函数同名的属性。假设函数是类方法或实例/绑定方法,则此“函数属性”将有另一个目录作为其值,其中包括除\uuuuuuu func\uuuu和\uuuu self\uuu之外的函数对象中的所有属性\uuuu func\uuuu包含另一个目录,即类本身中的函数目录,当然包含函数对象中的所有属性(例如,\uuuu func\uuu中的所有属性指向与类的函数目录中同名属性相同的对象)。当从实例调用函数时(当从实例调用函数时,实例的方法的\u

创建类的实例时,对于类定义中的每个函数,该实例的目录中将有一个与该函数同名的属性。假设函数是类方法或实例/绑定方法,则此“函数属性”将有另一个目录作为其值,其中包括除
\uuuuuuu func\uuuu
\uuuu self\uuu
之外的函数对象中的所有属性<代码>\uuuu func\uuuu包含另一个目录,即类本身中的函数目录,当然包含函数对象中的所有属性(例如,
\uuuu func\uuu
中的所有属性指向与类的函数目录中同名属性相同的对象)。当从实例调用函数时(当从实例调用函数时,实例的方法的
\uuuuu调用\uuuu
属性遵从
\uuu func\uuuu>时,实例的函数目录中的属性遵从
\uuu func\uuuuuu>目录中的相同属性)。那么,实例为什么还要创建这个
\uuuu func\uuu
属性呢?为什么不像静态方法那样,直接实例函数目录属性直接指向类函数目录属性?实例使用的内存似乎比它们需要的要多

为了更清楚地说明这种差异:

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__

查看等式,我们可以看到
\uuuu func\uuu
中的属性引用了由类本身创建的相同对象。但是,不在
\uuuu func\uuuu
中的属性(例如
\uuuu call\uuuu
)不引用同一对象,但它们可能会调用该对象。为什么要在
\uuuu func\uuuu
之外重新创建这些属性,而只是调用
\uuuu func\uuu
中的属性?为什么不转储dir(s.maxArea)中
\uuuuuu func\uuuu
中的属性,而
\uuuu self\uuuu
属性将表示该方法应作为实例方法调用?

它用于保存函数在内存中的位置

见:

一个示例类:

>>> class Test(object):
...     a = 'world'
...     def test_method(self, b='hello'):
...             print(b, self.a)
... 
工作示例:

>>> c = Test()
>>> c.test_method()
hello world
有与设置相关的代码、各种内部变量、参数、关键字参数(
\uuuuuu defaults\uuuuuu
\uuuuuuuuu defaults\uuuuuuuu
等),因此在调用该方法时,它具有有关如何调用该方法的信息。(参见示例,还请注意这里有python2/3的注意事项,请参见下面链接的
方法包装器
说明)

默认kwarg
b
示例:

>>> print(c.test_method.__defaults__)
('hello',)
其中是
测试
测试。测试方法
位于:

>>> print(c)
<__main__.Test object at 0x7fd274115550>
>>> print(c.test_method)
<bound method Test.test_method of <__main__.Test object at 0x7fd274115550>>
>>> print(c.test_method.__func__)
<function Test.test_method at 0x7fd274113598>

>>> c.test_method.__func__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test_method() missing 1 required positional argument: 'self'
调用
Test.Test\u方法时,该方法大致如下:

>>> c.test_method.__func__(c)
hello world
打电话怎么样?它是
函数的
方法包装器

  • 绑定/未绑定和
    方法包装之间的说明
另见:


它用于保存函数在内存中的位置

见:

一个示例类:

>>> class Test(object):
...     a = 'world'
...     def test_method(self, b='hello'):
...             print(b, self.a)
... 
工作示例:

>>> c = Test()
>>> c.test_method()
hello world
有与设置相关的代码、各种内部变量、参数、关键字参数(
\uuuuuu defaults\uuuuuu
\uuuuuuuuu defaults\uuuuuuuu
等),因此在调用该方法时,它具有有关如何调用该方法的信息。(参见示例,还请注意这里有python2/3的注意事项,请参见下面链接的
方法包装器
说明)

默认kwarg
b
示例:

>>> print(c.test_method.__defaults__)
('hello',)
其中是
测试
测试。测试方法
位于:

>>> print(c)
<__main__.Test object at 0x7fd274115550>
>>> print(c.test_method)
<bound method Test.test_method of <__main__.Test object at 0x7fd274115550>>
>>> print(c.test_method.__func__)
<function Test.test_method at 0x7fd274113598>

>>> c.test_method.__func__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test_method() missing 1 required positional argument: 'self'
调用
Test.Test\u方法时,该方法大致如下:

>>> c.test_method.__func__(c)
hello world
打电话怎么样?它是
函数的
方法包装器

  • 绑定/未绑定和
    方法包装之间的说明
另见:


您的答案包含了很好的信息,帮助我更好地理解了类方法。然而,我认为我的主要问题仍然没有答案。我知道
\uu func\uu
用于保存方法的目录,以帮助设置调用的上下文。但是,如果实例方法目录所要做的只是委托给
\uuuuu func\uuu
中的方法,那么为什么要重新定义与
\uuu func\uuu
中的属性完全相同的属性呢?静态方法不定义
\uuu func\uu
,因为它们只是简单地复制原始字典。为什么实例方法和类方法不一样,只包含
\uuuuuu self\uuuuuuu
?您的答案包含了很好的信息,帮助我更好地理解类方法。然而,我认为我的主要问题仍然没有答案。我知道
\uu func\uu
用于保存方法的目录,以帮助设置调用的上下文。但是,如果实例方法目录所要做的只是委托给
\uuuuu func\uuu
中的方法,那么为什么要重新定义与
\uuu func\uuu
中的属性完全相同的属性呢?静态方法不定义
\uuu func\uu
,因为它们只是简单地复制原始字典。为什么实例方法和类方法做的不一样,只是包含
\uuuuuuuuuuuuuuuuuuuuuu