在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。) ),并且与在类外部定义的内容相同。这是什么原因?
答案 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>
注意事项:
在类语句中,无论您使用def
还是lambda表达式,类名称都会添加到函数名称中。这表明该行为不是def
语句的一部分。同样,在实际创建class
对象本身之前 产生此输出。
在类语句之外,对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
侧边提示:在您的代码段中,z
是myClass
的一部分。 为简单起见,这与在构造函数中定义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 ... >