为什么类方法名以类名为前缀,而其他对象不是?

时间:2019-11-24 07:33:57

标签: python python-3.x

在Python中,如果我定义一个简单的类,如下所示:

>>> class myClass:
...  z = zip('abc', (97, 98, 99))
...  def meth(self):
...   print(self)
...
>>>

,然后在提示符下输入以下内容:

>>> myClass.meth
<function myClass.meth at 0x00639540>
>>> myClass.z
<zip object at 0x006432B0>
>>>

我发现Python将函数对象表示为属于该类( myClass.meth ),但该属性的字符串表示形式却不是(该名称的前面没有 myClass。) ),并且与在类外部定义的内容相同。这是什么原因?

3 个答案:

答案 0 :(得分:2)

这似乎是在class语句中定义函数的副作用。在全局范围内定义方法并显式调用type不会将类名添加到函数名中。

考虑以下代码:

class myClass:
    def meth(self):
        print(self)
    print("meth:", repr(meth))
    x = lambda self: print(self)
    print("x:", repr(x))


def mymeth(self):
    print(self)

print("mymeth:", repr(mymeth))
C = type('C', (object,), {'mymeth': mymeth})
print("mymeth:", repr(C.mymeth))

输出为

meth: <function myClass.meth at 0x1055c6b90>
x: <function myClass.<lambda> at 0x1055c6dd0>
mymeth: <function mymeth at 0x1055c6b00>
mymeth: <function mymeth at 0x1055c6b00>

注意事项:

  1. 在类语句中,无论您使用def还是lambda表达式,类名称都会添加到函数名称中。这表明该行为不是def语句的一部分。同样,在实际创建class对象本身之前 产生此输出。

  2. 在类语句之外,对type的调用不会将类名添加到函数名中。这表明修改函数名称的是class语句本身,而不是创建类的行为。


关于为什么是这种情况?据推测,已决定在function.__repr__的输出中添加“完全限定”的方法名称以进行调试是有用的,但我只是在推测。

答案 1 :(得分:0)

z只是一个名称,它拥有的值是内置zip类,它不是myClass的一部分。

答案 2 :(得分:0)

这是因为通过调用myclass.meth,您只是指向函数所在的内存位置。

但是对于myClass.z,您只是在调用z返回的内容。 类似于以下情况:

class myClass:
    x = 2
    z = zip('abc', (97, 98, 99))
    ...

然后myClass.x将是2

侧边提示:在您的代码段中,zmyClass的一部分。 为简单起见,这与在构造函数中定义self.z = zip('abc', (97, 98, 99))相同。 为了清楚了解为什么真的不喜欢这样做,我会检查一下 Class vs Instance attributes

添加的示例:
添加另一个可能对该问题有所启发的示例,请考虑一下

def some_fn():
   return 'hello world'

class A(object):
   p = some_fn

然后

A.p
>> <function some_fn at 0x7f00fefbef80>

>>> <function A.some_fn at ... >