All methods in python classes behaving like static
就在最近,我注意到一个新概念:Python中的class function。
(注意:不是ask class方法,而是类函数,比如下一个代码中的fun)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class A:
def fun():
print("fun")
@staticmethod
def fun2():
print("fun2")
A.fun()
A.fun2()
# updated
print(A.__dict__)
# {'__module__': '__main__', 'fun': <function A.fun at 0x0000014C658F30D0>, 'fun2': <staticmethod object at 0x0000014C658E1C50>, '__dict__': , '__weakref__': , '__doc__': None} |
如果执行上述代码:
Python 2输出:
Traceback (most recent call last): File"a.py", line 9, in
A.fun() TypeError: unbound method fun() must be called with A instance as first argument (got nothing instead)
Python 3输出:
fun
fun2
而且,在python3中,它似乎被称为类函数,不再是一个方法。
所以,我的问题是:为什么这种变化?因为我们已经可以使用@staticmethod在类中定义一些实用函数。
- 当然,我仍然可以使用staticmethod,只是恐怕我会错过一些新特性,就像关于"类方法和静态方法"比较的旧问题一样。最后,我们都知道我们可以使用类方法来创建静态方法不能创建的工厂方法。那么现在这个比较如何呢?
- 为什么实例方法可以在python3中作为类方法调用?
这是因为默认情况下,python 3类中的所有函数都具有静态行为。python 3删除了未绑定方法的概念。可以使用类对象本身调用类的所有成员方法,正如您所做的那样。
因此,除了您的代码外,还允许使用此代码:
1 2 3 4 5
| class A:
def func(self):
print('Hello')
A.func(123) |
这可能是为了方便起见,避免了在某些情况下必须编写@staticmethod,还可以让您将实例方法与其他类型的对象重用,如上面的代码片段所示。
函数没有显示为staticmethod,因为它没有。正如@aran fey指出的那样,可以对类的一个实例调用一个无参数的静态方法,这就是为什么我们在python3中有@staticmethod。
(请检查编辑历史记录中此答案的旧版本和错误版本)
- 似乎很合理,但看更新,我把这门课的口述打印出来了。如果只是为了方便起见,为什么fun的类型不是staticmethod?你能分享一些我可以参考的可以证明你想法的链接吗?
- 编辑:不幸的是,我找不到任何文档来支持这一点。
- 好吧,我赞成这个答案,因为这似乎是合理的,再等一段时间,看看是否有其他人建议的官方文件。如果没有,将接受这个答案。谢谢。
- python 3类中的无参数函数在默认情况下不是staticmethods。你能包括一个代码示例来说明你的意思吗?
- 是的,他们没有,我已经解释了为什么他们不能
- "如果没有指定自变量,它会有效地使函数与静态方法相同。"false。A().fun()会抛出一个异常,但A().fun2()不会。"由于向后兼容的原因,decorator@staticmethod可能没有被删除。"又错了。因为它有一个目的,所以它没有被移除。
- @阿兰·费伊,我也注意到了与A()的通话。在重复的建议中,它说:The concept of"unbound methods" has been removed from the language. When referencing a method as a class attribute, you now get a plain function object.,这意味着它只是a plain function object,这是否意味着它就像一个类外的函数?与A级无关?
- @拉各姆,这有点难回答。的确,在类中定义的函数和在类外部定义的函数没有区别。但是您必须记住,所有函数都是描述符,如果通过实例(如A().fun()访问),则它们的行为会有所不同。它的全部含义是,如果您在类外部定义一个函数,然后将它添加到类(如A.fun3 = fun3)中,它的行为将与它一直在类中定义的行为完全相同。
- @阿兰·费伊,但是在Python3中使用@staticmethod有什么目的呢?它是否只允许通过类实例进行调用?
- @是的,就是这样。
- @Aran Fey如果是这样的话,我会进一步研究这个问题,并编辑答案以提供正确的信息。
- @阿兰·菲纠正了我的回答