Why does a method within a class work even if not marked with @classmethod or @staticmethod?
我不熟悉Python,只是了解它的对象/类的实现。我理解实例方法、类方法和静态方法之间的区别,但我不理解的是,为什么没有修饰成@class method或@static method的方法可以从类本身调用。
我非常(非常)基本的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class TestClass:
def __init__(self):
pass
@staticmethod
def print_static_stuff(stuff):
print(stuff)
def print_stuff(stuff):
print(stuff)
TestClass.print_stuff("stuff") # prints"stuff"
TestClass.print_static_stuff("static stuff") # prints"static stuff" |
当对类调用方法print_stuff()时,它似乎充当一个静态方法,将参数作为单个参数,而不是类(cls)。为什么不能在类上调用未用@staticClass修饰的方法?这是出于设计还是只是一个奇怪的副作用,为什么?从我到目前为止所学到的,按照设计,Python几乎没有"奇怪的副作用"。
- 看看TestClass.print_self('hello')做了什么,享受开明的幸福……
- 换句话说,"方法"只是正常的功能。但是,如果通过实例访问,则会隐式地将实例传递给第一个参数。注意,名称self只是一个惯例。你可以随意命名第一个参数。
- 看看另一个问题的答案,我试着用一些例子来解释这个问题。另外,要认识到,TestClass.print_stuff返回一个函数对象:,wheras t.print_stuff返回一个绑定方法对象:>。
- 如果你想看看引擎盖下发生了什么,这是一篇博客文章,解释了它正在使用描述符在python中重新实现Function和Method对象,这就是它在引擎盖下实际实现的方式!.
- 我确实了解实例方法,我的问题是关于类方法。我修改了我的问题,使之更清楚。感谢您的回复!
- 不,您显然不理解实例方法,否则您将理解为什么TestClass.print_stuff('stuff')实际打印"stuff"。所有方法都属于该类。python中的方法只是类名称空间中的普通函数,它们被隐式绑定到一个实例(使用引擎盖下面的描述符协议)。我再次敦促你阅读我发布的各种链接。
- @阿瑞维拉加,我明白你的意思,但我还是觉得你没明白我的意思。我说的不是从实例调用的函数或方法,而是直接从类定义调用的,甚至没有基于类创建任何对象。是否可以安全地说类定义可以简单地作为代码中的名称空间,即使它从未实例化?可能不是很好地使用类,但是仍然是一种用法?
- 同样,如果您不理解所有方法(包括实例方法)都属于类,并且可以直接从类中调用,那么您就不理解Python中的实例方法。所以,可以肯定地说,类可以简单地作为一个名称空间。staticmethod修饰器所做的唯一一件事是确保在对实例调用方法时,不会将实例作为第一个参数传递。基本上,你可以把my_instance.my_method()看作MyClass.my_method(my_instance)的句法糖。
名为self的第一个参数只是一个约定。该实例将作为第一个位置参数传递,与您所命名的参数无关(在本例中,您称它为stuff)。
- 我得到了实例方法,但是我在问关于类方法的问题,并相应地修改了我的问题。谢谢你的回答!