Python 为什么类方法名的前缀是类名,而不是其他对象?
在Python中,如果我定义一个简单类,如下所示:Python 为什么类方法名的前缀是类名,而不是其他对象?,python,python-3.x,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.
>>> 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>
>>>
>myClass.meth
>>>myClass.z
>>>
我发现Python将函数对象表示为属于类(myClass.meth),但属性的字符串表示形式不是(它的名称前面没有myClass。),与在类外部定义时没有区别。原因是什么?
z
只是一个名称,它所持有的值是内置的zip
类,它不属于myClass这是因为通过调用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))
是一样的。
为了弄清楚为什么我真的不喜欢这样做,我会检查一下
添加示例:
添加另一个可能对这个问题有启发的例子,请考虑这个
def some_fn():
返回“你好,世界”
A类(对象):
p=一些_fn
然后
A.p
>>
而不是
>>> <function A.some_fn at ... >
>
这似乎是在类中定义函数的副作用。在全局范围定义方法并显式调用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>
方法:
x:
mymeth:
mymeth:
注意事项:
在class语句中,无论使用def
还是lambda表达式,都会将类名添加到函数名中。这表示该行为不是def
语句的一部分。此外,此输出是在实际创建类
对象本身之前生成的
在class语句之外,对type
的调用不会将类名添加到函数名中。这表明修改函数名的是class
语句本身,而不是创建类的行为
为什么会这样?据推测,在函数的输出中添加一个“完全限定”的方法名是有用的。为了调试的目的,我只是猜测一下。嗨。但“冰毒”也是一个名字。“z”和“meth”都是绑定到对象的名称。当在提示符下输入其中一个时,返回的描述是名称引用的对象,在这种情况下,我们将函数对象作为类的一部分接收回来,而不是zip对象。@learner类是可执行语句,因此使用myClass
时执行z=zip()。函数仅在显式调用时执行,因此它们被绑定到类,但只有在类中,类名是函数位置的一部分时才执行。尝试myClass().meth
,您将获得所需的绑定方法myClass.meth
。现在将x='asd'
添加到myClass
中,看看你得到了什么。我不确定我是否理解。。我们知道,在提示符下输入字符串不会像zip对象那样返回字符串表示形式,但是我添加了x='asd',它返回字符串本身('asd')。。这里的重点是什么@Learner显示它返回值,而不是类似于myClass.str
。谢谢。。虽然说实话,我真的不能理解你的想法,这里没有存储在z或任何其他名称中的内容。“z”引用内存中的zip对象。当我们在提示符处输入这些绑定变量名称时,我们将返回它们所引用的任何内容。有些对象按原样返回(例如示例中的整数,字符串也是如此),但对于其他对象,例如zip对象和函数对象,返回一个文本表示(描述),关于这个描述,我要问:为什么它将函数对象描述为属于类(前面有类名和一个点),但zip对象不是….?我的措辞很糟糕。当我提到“z
的内容”时,我指的是关于z
输出的内容。从zip()
()的文档中,zip()
输出一个迭代器对象,迭代器对象负责生成其输出。因此,所讨论的地址(
)不必绑定到myClass
,因为它实际上指向python.Hi中的一个内置函数。感谢您确认我所问的问题。尽管我认为这不是问题“完全限定名称”是否显示(这可能不一致),函数确实有这样的归属/成员身份,而zip对象没有,Python显示的字符串rep简单地说明了这一点。我认为主要区别在于并非所有对象都有存储名称的属性;函数
对象都有。这使得函数更容易提供一个比zip
更自定义的名称,而不必动态地重新定义\uuuuuu repr\uuuuuu
。谢谢。请告诉我,类对象是什么时候创建的?最终,是什么时候调用对象的。如果没有重写任何\uuuu call\uuuuu
或\uuuuuuuuu new\ucode>方法,则进程为:C()
调用C.\uu调用
,解析为对象。\uu调用
,调用C.\uu新建
,解析为对象。\uu新建
,返回新对象。
meth: <function myClass.meth at 0x1055c6b90>
x: <function myClass.<lambda> at 0x1055c6dd0>
mymeth: <function mymeth at 0x1055c6b00>
mymeth: <function mymeth at 0x1055c6b00>