用@staticmethod修饰的方法和用@classmethod修饰的方法有什么区别?
当前回答
当存在继承时,就会出现差异。
假设有两个类——父类和子类。如果要使用@staticmethod,print_name方法应该写两次,因为类的名称应该写在打印行中。
class Parent:
_class_name = "Parent"
@staticmethod
def print_name():
print(Parent._class_name)
class Child(Parent):
_class_name = "Child"
@staticmethod
def print_name():
print(Child._class_name)
Parent.print_name()
Child.print_name()
但是,对于@classmethod,不需要编写print_name方法两次。
class Parent:
_class_name = "Parent"
@classmethod
def print_name(cls):
print(cls._class_name)
class Child(Parent):
_class_name = "Child"
Parent.print_name()
Child.print_name()
其他回答
类方法将类作为隐式第一参数接收,就像实例方法接收实例一样。它是一个绑定到类而不是类的对象的方法。它可以访问类的状态,因为它使用指向类而不是对象实例的类参数。它可以修改将应用于类的所有实例的类状态。例如,它可以修改将适用于所有实例的类变量。
另一方面,与类方法或实例方法相比,静态方法不接收隐式第一个参数。并且无法访问或修改类状态。它只属于类,因为从设计的角度来看,这是正确的方法。但就功能而言,在运行时,它并不与类绑定。
作为指导,使用静态方法作为实用程序,使用类方法作为工厂。或者可以定义一个单例。并使用实例方法对实例的状态和行为进行建模。
希望我清楚!
我想在前面所有答案的基础上补充以下内容,这不是官方的,但符合标准。
首先,你可以考虑总是给予最少的特权。因此,如果您不需要特定于实例的内容,请将其设置为类方法。如果您不需要特定于类的内容,请将其设置为静态方法。
第二件事是考虑您可以通过创建的方法类型进行通信。静态方法-助手函数意味着在类本身之外使用。类函数-可以在没有实例化的情况下调用,但意味着只能与该类一起使用-否则将是一个静态方法!实例方法-仅用于实例。
这可以帮助您沟通模式以及如何使用代码。
class Foo:
@classmethod
def bar(cls, id: int = None):
query = session.query(
a.id,
a.name,
a.address,
)
if id is not None:
query = query.filter(a.id == id)
return query
例如,上面提到的——没有理由说明方法栏不能是静态的。然而,通过将其设置为类方法,您可以传达它应该由类本身使用,而不是作为其他地方使用的助手函数!
请记住,以上内容不是官方的,而是我个人的偏好
@classmethod:可用于创建对该类创建的所有实例的共享全局访问。。。。。比如由多个用户更新记录。。。。我特别发现它在创建单件时也很有用。:)
@静态方法:与关联的类或实例无关。。。但为了可读性,可以使用静态方法
对iPython中其他相同方法的快速破解表明,@staticmethod产生了边际性能增益(以纳秒为单位),但在其他方面它似乎没有任何作用。此外,在编译过程中通过staticmethod()处理方法的额外工作(这在运行脚本时任何代码执行之前发生)可能会抵消任何性能提升。
为了代码的可读性,我会避免@staticmethod,除非您的方法将用于纳秒计数的工作量。
您可能需要考虑以下两者之间的区别:
class A:
def foo(): # no self parameter, no decorator
pass
and
class B:
@staticmethod
def foo(): # no self parameter
pass
这在python2和python3之间发生了变化:
蟒蛇2:
>>> A.foo()
TypeError
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()
蟒蛇3:
>>> A.foo()
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()
因此,在python3中,对仅直接从类调用的方法使用@staticmethod已成为可选的。如果要从类和实例调用它们,仍然需要使用@staticmethoddecorator。
其他案例都被未用的答案很好地涵盖了。
推荐文章
- 如何删除Python中的前导空白?
- python中的assertEquals和assertEqual
- 如何保持Python打印不添加换行符或空格?
- PHP中接口的意义是什么?
- 为什么Python的无穷散列中有π的数字?
- Python 3.7数据类中的类继承
- 如何在PyTorch中初始化权重?
- 计数唯一的值在一列熊猫数据框架像在Qlik?
- 使用Pandas将列转换为行
- 从matplotlib中的颜色映射中获取单个颜色
- 虚拟方法和抽象方法的区别
- 将Pandas或Numpy Nan替换为None以用于MysqlDB
- 使用pandas对同一列进行多个聚合
- 使用Python解析HTML
- django MultiValueDictKeyError错误,我如何处理它