python @classmethod和@staticmethod的区别
2017-09-25 00:00
567 查看
摘要: @classmethod和@staticmethod的区别
也许一些例子会有帮助:注意
下面是一个对象实体调用方法的常用方式.对象实体
用classmethod装饰,隐藏的传递给第一个参数的是对象实体的类(
你也可以用类调用
用staticmethod来装饰,不管传递给第一个参数的是
静态方法被用来组织类之间有逻辑关系的函数.
如果使用
最后剩下静态方法,说到底它就是一个函数.
总结:
普通类方法:第一个参数必须传,作为接收
@classmethod(类方法): 第一个参数必须传,作为接收
@staticmethod(静态方法):
区别本质有了,具体几个应用如下:
最直接应用就是,加了这2个装饰器,就可以不需要实例化,直接通过
1. 构造多个构造函数
由于python里没有java的重载机制(java里同方法名不同参数认为是不同的方法,python里只要方法名唯一),可通过classmethod的特性构造多个构造函数
接着上面,假如字符串格式不是'dd-mm-yyyy'格式,执行from_string就不会得到想要的结果,这时我们要检验这个值,此时staticmethod就会很合适
也许一些例子会有帮助:注意
foo,
class_foo和
static_foo参数的区别:
class A(object): a = 'a' def __init__(self): self.b = 'b' def foo(self,x): print "executing foo(%s,%s)"%(self,x) @classmethod def class_foo(cls,x): print cls.static_foo('2') cls.name = 'A1' print dir(cls) print "executing class_foo(%s,%s)"%(cls,x) @staticmethod def static_foo(x): print "executing static_foo(%s)"%x a=A()
下面是一个对象实体调用方法的常用方式.对象实体
a被隐藏的传递给了第一个参数.
a.foo(1) # executing foo(<__main__.A object at 0xb7dbef0c>,1)
用classmethod装饰,隐藏的传递给第一个参数的是对象实体的类(
class A)而不是
self.
a.class_foo(1) # executing class_foo(<class '__main__.A'>,1)
你也可以用类调用
class_foo.实际上,如果你把一些方法定义成
classmethod,那么实际上你是希望用类来调用这个方法,而不是用这个类的实例来调用这个方法.
A.foo(1)将会返回一个
TypeError错误,
A.class_foo(1)将会正常运行:
A.foo(1) #TypeError: unbound method foo() must be called with A instance as first argument (got str instance instead) # 这时可想到把示例化的a传进去怎么样?结果证实可行,和a.foo(1)效果一样,但不建议这样使用 # 其实f1 = A.foo, a = A(), f2 = a.foo, f1是unbound method,f2是bound method # 具体可见https://my.oschina.net/u/914655/blog/1546281 A.foo(a, 1) # executing foo(<__main__.A object at 0xb7dbef0c>,1) A.class_foo(1) # executing class_foo(<class '__main__.A'>,1)
用staticmethod来装饰,不管传递给第一个参数的是
self(对象实体)还是
cls(类).它们的表现都一样:
a.static_foo(1) # executing static_foo(1) A.static_foo('hi') # executing static_foo(hi)
静态方法被用来组织类之间有逻辑关系的函数.
foo只是个函数,但是当你调用
a.foo的时候你得到的不仅仅是一个函数,你得到的是一个第一个参数绑定到
a的"加强版"函数. python解析器会自动把a示例绑定到foo的第一个参数参数上
a绑定了
foo.下面可以知道什么叫"绑定"了:
print(a.foo) # <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
如果使用
a.class_foo, 是
A绑定到了
class_foo而不是实例
a.
print(a.class_foo) # <bound method type.class_foo of <class '__main__.A'>>
最后剩下静态方法,说到底它就是一个函数.
a.static_foo只是返回一个不带参数绑定的函数.
static_foo和
a.static_foo只需要一个参数.
print(a.static_foo) # <function static_foo at 0xb7d479cc>
总结:
普通类方法:第一个参数必须传,作为接收
类实例对象的参数。也即持有类实例对象,需要实例化的类才能调用或者直接把实例化参数传入第一个,见上面
@classmethod(类方法): 第一个参数必须传,作为接收
类对象的参数。也即持有类对象,在不需实例化的情况下调用类的属性等
@staticmethod(静态方法):
区别本质有了,具体几个应用如下:
最直接应用就是,加了这2个装饰器,就可以不需要实例化,直接通过
类名.函数名()来调用,有利于组织代码,把属于某个类的函数,但又不需实例化的给放进类里去,同时有利于命名空间的整洁。
1. 构造多个构造函数
由于python里没有java的重载机制(java里同方法名不同参数认为是不同的方法,python里只要方法名唯一),可通过classmethod的特性构造多个构造函数
class Date(object): def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year 比如Date类,我们要实例化它,必须传入day, month, year 加入我们有个string_date = '11-4-2017' 必须按如下方式处理 day, month, year = map(int, string_date.split('-')) date1 = Date(day, month, year) c++ java等语言有重载的特性,但python没有,这时我们就可以通过classmethod来实现 @classmethod def from_string(cls, date_as_string): day, month, year = map(int, date_as_string.split('-')) date1 = cls(day, month, year) return date1 # 现在直接通过调用from_string即可 date2 = Date.from_string('11-09-2012') # 而且有以下好处 # 1. 针对此类的日期解析函数在本类里,方便管理,而且可重用 # 2. cls是一个持有类本身的对象,而不是类的一个实例。这很酷,因为如果我们继承我们的Date类,所有的孩子也将有from_string定义。
接着上面,假如字符串格式不是'dd-mm-yyyy'格式,执行from_string就不会得到想要的结果,这时我们要检验这个值,此时staticmethod就会很合适
@staticmethod def is_date_valid(date_as_string): day, month, year = map(int, date_as_string.split('-')) return day <= 31 and month <= 12 and year <= 3999 # usage: is_date = Date.is_date_valid('11-09-2012')
相关文章推荐
- python -- @classmethod @staticmethod区别和使用
- python中staticmethod classmethod及普通函数的区别
- python中staticmethod classmethod及普通函数的区别
- python @staticmethod @classmethod 区别
- python @classmethod 和 @staticmethod区别,以及类中方法参数cls和self的区别
- Python @classmethod和@staticmethod区别
- python @classmethon @staticmethod 的使用及区别
- python中staticmethod classmethod及普通函数的区别
- python @classmethod和@staticmethod的区别
- 通过代码学习python之@property,@staticmethod,@classmethod
- Python: classmethod & staticmethod 区别
- Python:staticmethod vs classmethod
- Python 实例方法、@staticmethod和@classmethod
- Python中classmethod与staticmethod区别
- python------@staticmethod和@classmethod的作用与区别
- Python classmethod staticmethod 进价学习
- python classmethod staticmethod
- python中@classmethod与@staticmethod的区别和用法
- Class method differences in Python: bound, unbound and static
- 【python】classmethod & staticmethod 区别