gpt4 book ai didi

python - Python 中有超过三种类型的方法吗?

转载 作者:太空狗 更新时间:2023-10-30 00:53:46 25 4
gpt4 key购买 nike

我知道 Python 中至少有 3 种方法具有不同的第一个参数:

  1. 实例方法 - 实例,即 self
  2. 类方法 - 类,即 cls
  3. 静态方法 - 无

这些经典方法在下面的 Test 类中实现,包括一个常用方法:

class Test():

def __init__(self):
pass

def instance_mthd(self):
print("Instance method.")

@classmethod
def class_mthd(cls):
print("Class method.")

@staticmethod
def static_mthd():
print("Static method.")

def unknown_mthd():
# No decoration --> instance method, but
# No self (or cls) --> static method, so ... (?)
print("Unknown method.")

在 Python 3 中,可以安全地调用 unknown_mthd,但在 Python 2 中会引发错误:

>>> t = Test()

>>> # Python 3
>>> t.instance_mthd()
>>> Test.class_mthd()
>>> t.static_mthd()
>>> Test.unknown_mthd()

Instance method.
Class method.
Static method.
Unknown method.

>>> # Python 2
>>> Test.unknown_mthd()
TypeError: unbound method unknown_mthd() must be called with Test instance as first argument (got nothing instead)

此错误表明 Python 2 不打算使用这种方法。现在允许使用它可能是由于 Python 3 中取消了未绑定(bind)方法 (REF 001)。此外,unknown_mthd 不接受 args,它可以绑定(bind) 由类调用,如静态方法 Test.unknown_mthd()。但是,它不是显式静态方法(没有装饰器)。

问题

  1. 在 Python 3 的设计中是否有意以这种方式制作方法(没有参数,但没有明确装饰为静态方法)?已更新
  2. 在经典的方法类型中,unknown_mthd是什么类型的方法?
  3. 为什么 unknown_mthd 可以在不传递参数的情况下被类调用?

一些初步检查产生不确定的结果:

>>> # Types
>>> print("i", type(t.instance_mthd))
>>> print("c", type(Test.class_mthd))
>>> print("s", type(t.static_mthd))
>>> print("u", type(Test.unknown_mthd))
>>> print()

>>> # __dict__ Types, REF 002
>>> print("i", type(t.__class__.__dict__["instance_mthd"]))
>>> print("c", type(t.__class__.__dict__["class_mthd"]))
>>> print("s", type(t.__class__.__dict__["static_mthd"]))
>>> print("u", type(t.__class__.__dict__["unknown_mthd"]))
>>> print()

i <class 'method'>
c <class 'method'>
s <class 'function'>
u <class 'function'>

i <class 'function'>
c <class 'classmethod'>
s <class 'staticmethod'>
u <class 'function'>

第一组类型检查表明 unknown_mthd 类似于静态方法。第二个表明它类似于实例方法。我不确定这种方法是什么或者为什么应该在经典方法上使用它。我将不胜感激有关如何更好地检查和理解它的一些建议。谢谢。

最佳答案

一些背景知识:在 Python 2 中,“常规”实例方法可以产生两种方法对象,具体取决于您是通过实例还是类访问它们。如果您执行了 inst.meth(其中 inst 是该类的一个实例),您将获得一个绑定(bind)方法对象,它跟踪它附加到哪个实例,并且将其作为 self 传递。如果你执行了 Class.meth(其中 Class 是类),你会得到一个未绑定(bind)的方法对象,它没有固定的 self 值,但仍然进行了检查以确保在您调用它时传递了相应类的 self

在 Python 3 中,未绑定(bind)的方法被移除。执行 Class.meth 现在只为您提供“普通”函数对象,根本不检查参数。

Was making a method this way intentional in Python 3's design?

如果您的意思是,移除未绑定(bind)方法是有意的,那么答案是肯定的。可以看Guido的讨论on the mailing list .基本上决定未绑定(bind)方法增加复杂性却收效甚微。

Among the classic method types, what type of method is unknown_mthd?

它是一个实例方法,但是是一个坏掉的方法。当您访问它时,会创建一个绑定(bind)方法对象,但由于它不接受任何参数,因此无法接受 self 参数,因此无法成功调用。

Why can unknown_mthd be called by the class without passing an argument?

在 Python 3 中,未绑定(bind)方法被移除,因此 Test.unkown_mthd 只是一个普通函数。没有发生包装来处理 self 参数,因此您可以将它作为不接受任何参数的普通函数来调用。在 Python 2 中,Test.unknown_mthd 是一个未绑定(bind)的方法对象,它具有强制传递适当类的 self 参数的检查;同样,由于该方法不接受任何参数,因此此检查失败。

关于python - Python 中有超过三种类型的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43949280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com