用@staticmethod修饰的方法和用@classmethod修饰的方法有什么区别?
当前回答
我开始用C++学习编程语言,然后是Java,然后是Python,所以这个问题也困扰了我,直到我理解了每种语言的简单用法。
类方法:Python不像Java和C++那样没有构造函数重载。为了实现这一点,可以使用classmethod。以下示例将对此进行解释
让我们考虑一个Person类,它接受两个参数first_name和last_name,并创建Person的实例。
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
现在,如果您需要仅使用一个名称(仅使用first_name)创建一个类,那么在Python中不能这样做。
当您尝试创建对象(实例)时,这将给您一个错误。
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __init__(self, first_name):
self.first_name = first_name
然而,您可以使用@classmethod实现以下相同的功能
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@classmethod
def get_person(cls, first_name):
return cls(first_name, "")
静态方法:这相当简单,它不绑定到实例或类,您可以使用类名简单地调用它。
所以,在上面的示例中,假设您需要验证first_name不应超过20个字符,您可以简单地这样做。
@staticmethod
def validate_name(name):
return len(name) <= 20
您可以使用类名调用
Person.validate_name("Gaurang Shah")
其他回答
@classmethod:可用于创建对该类创建的所有实例的共享全局访问。。。。。比如由多个用户更新记录。。。。我特别发现它在创建单件时也很有用。:)
@静态方法:与关联的类或实例无关。。。但为了可读性,可以使用静态方法
对iPython中其他相同方法的快速破解表明,@staticmethod产生了边际性能增益(以纳秒为单位),但在其他方面它似乎没有任何作用。此外,在编译过程中通过staticmethod()处理方法的额外工作(这在运行脚本时任何代码执行之前发生)可能会抵消任何性能提升。
为了代码的可读性,我会避免@staticmethod,除非您的方法将用于纳秒计数的工作量。
python官方文档:
@分类法
类方法将类作为隐式第一个参数,就像instance方法接收该实例。要声明类方法,请使用成语:C类:@分类法定义f(cls,arg1,arg2,…):。。。@classmethod表单是一个函数decorator–请参见函数中的函数定义详细定义。它可以在类上调用(例如C.f())或实例(例如C().f())。实例是除了它的类之外,都被忽略。如果类方法用于派生类,派生类对象是作为隐含的第一个参数传递。类方法不同于C++或Java静态方法。如果你愿意这些,请参见本文中的staticmethod()部分
@静态方法
静态方法不接收隐式第一个参数。声明静态方法,使用这个成语:C类:@静态方法定义f(arg1,arg2,…):。。。@staticmethod表单是一个函数decorator–请参见函数中的函数定义详细定义。它可以在类上调用(例如C.f())或实例(例如C().f())。实例是除了它的类之外,都被忽略。Python中的静态方法类似类似于Java或C++中的那些。对于更高级的概念,请参见classmethod()。
太长,读不下去了
静态方法本质上是绑定到类(及其实例)的函数
类方法本质上是一种可继承的静态方法。
有关详细信息,请参阅其他人的优秀答案。
要决定是使用@staticmethod还是@classmethod,必须查看方法内部。如果您的方法访问类中的其他变量/方法,请使用@classmethod。另一方面,如果您的方法不涉及类的任何其他部分,则使用@staticmethod。
class Apple:
_counter = 0
@staticmethod
def about_apple():
print('Apple is good for you.')
# note you can still access other member of the class
# but you have to use the class instance
# which is not very nice, because you have repeat yourself
#
# For example:
# @staticmethod
# print('Number of apples have been juiced: %s' % Apple._counter)
#
# @classmethod
# print('Number of apples have been juiced: %s' % cls._counter)
#
# @classmethod is especially useful when you move your function to another class,
# you don't have to rename the referenced class
@classmethod
def make_apple_juice(cls, number_of_apples):
print('Making juice:')
for i in range(number_of_apples):
cls._juice_this(i)
@classmethod
def _juice_this(cls, apple):
print('Juicing apple %d...' % apple)
cls._counter += 1
推荐文章
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外
- 如何获取在Python中捕获的异常的名称?
- 第一次出现的值大于现有值的Numpy
- 如何从Python函数中返回两个值?
- 前一个月的Python日期
- Python中方括号括起来的列表和圆括号括起来的列表有什么区别?
- Python日志记录不输出任何东西
- 接口方法的最终参数-有什么意义?
- 每n秒运行特定代码
- SQLAlchemy是否有与Django的get_or_create等价的函数?
- 如何将python datetime转换为字符串,具有可读格式的日期?
- 美丽的汤和提取div及其内容的ID