@staticmethod和@classmethod的用法
来源:互联网 发布:sql语句是什么 编辑:程序博客网 时间:2024/06/04 19:51
讲解一
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,
- @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。
下面上代码。
class A(object): bar = 1 def foo(self): print 'foo' @staticmethod def static_foo(): print 'static_foo' print A.bar @classmethod def class_foo(cls): print 'class_foo' print cls.bar cls().foo() ###执行 A.static_foo() A.class_foo()
输出
static_foo1class_foo1foo
讲解二
类中最常用的方法是实例方法, 即通过通过实例作为第一个参数的方法。
举个例子,一个基本的实例方法就向下面这个:
class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data)ik1 = Kls('arun')ik2 = Kls('seema')ik1.printd()ik2.printd()
这会给出如下的输出:
arunseema
然后看一下代码和示例图片:
- 1,2参数传递给方法.
- 3 self参数指向当前实例自身.
- 4 我们不需要传递实例自身给方法,Python解释器自己会做这些操作的
如果现在我们想写一些仅仅与类交互而不是和实例交互的方法会怎么样呢? 我们可以在类外面写一个简单的方法来做这些,但是这样做就扩散了类代码的关系到类定义的外面. 如果像下面这样写就会导致以后代码维护的困难:
def get_no_of_instances(cls_obj): return cls_obj.no_instclass Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1ik1 = Kls()ik2 = Kls()print(get_no_of_instances(Kls))
输出:
2
@classmethod
我们要写一个只在类中运行而不在实例中运行的方法. 如果我们想让方法不在实例中运行,可以这么做:
def iget_no_of_instance(ins_obj): return ins_obj.__class__.no_instclass Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1ik1 = Kls()ik2 = Kls()print iget_no_of_instance(ik1)
输出
2
在Python2.2以后可以使用@classmethod装饰器来创建类方法.
class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 @classmethod def get_no_of_instance(cls_obj): return cls_obj.no_instik1 = Kls()ik2 = Kls()print ik1.get_no_of_instance()print Kls.get_no_of_instance()
输出:
22
这样的好处是: 不管这个方式是从实例调用还是从类调用,它都用第一个参数把类传递过来.
@staticmethod
经常有一些跟类有关系的功能但在运行时又不需要实例和类参与的情况下需要用到静态方法. 比如更改环境变量或者修改其他类的属性等能用到静态方法. 这种情况可以直接用函数解决, 但这样同样会扩散类内部的代码,造成维护困难.
比如这样:
IND = 'ON'def checkind(): return (IND == 'ON')class Kls(object): def __init__(self,data): self.data = datadef do_reset(self): if checkind(): print('Reset done for:', self.data)def set_db(self): if checkind(): self.db = 'new db connection' print('DB connection made for:',self.data)ik1 = Kls(12)ik1.do_reset()ik1.set_db()
输出:
Reset done for: 12DB connection made for: 12
如果使用@staticmethod就能把相关的代码放到对应的位置了.
IND = 'ON'class Kls(object): def __init__(self, data): self.data = data @staticmethod def checkind(): return (IND == 'ON') def do_reset(self): if self.checkind(): print('Reset done for:', self.data) def set_db(self): if self.checkind(): self.db = 'New db connection' print('DB connection made for: ', self.data)ik1 = Kls(12)ik1.do_reset()ik1.set_db()
输出:
Reset done for: 12DB connection made for: 12
下面这个更全面的代码和图示来展示这两种方法的不同
@staticmethod 和 @classmethod的不同
class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data) @staticmethod def smethod(*arg): print('Static:', arg) @classmethod def cmethod(*arg): print('Class:', arg)
>>> ik = Kls(23)>>> ik.printd()23>>> ik.smethod()Static: ()>>> ik.cmethod()Class: (<class '__main__.Kls'>,)>>> Kls.printd()TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)>>> Kls.smethod()Static: ()>>> Kls.cmethod()Class: (<class '__main__.Kls'>,)
- @staticmethod和@classmethod的用法
- Python中@staticmethod和@classmethod的区别和用法
- python的staticmethod和classmethod
- staticmethod和classmethod的区别
- python的@classmethod和@staticmethod
- python中@classmethod与@staticmethod的区别和用法
- Python中classmethod()和staticmethod()的用法
- Python @staticmethod@classmethod用法
- Python @staticmethod 和 @classmethod 的异同
- 【Python】Staticmethod和classmethod的区别
- Python中的staticmethod和classmethod 的异同
- python中staticmethod和classmethod的区别
- Python的classmethod和staticmethod区别
- python中classmethod和staticmethod的区别
- Python @classmethod 和 @staticmethod的比较
- python的classmethod和staticmethod方法
- @staticmethod和@classmethod的作用与区别
- python中staticmethod和classmethod的区别
- 使用Proguard混淆jar包
- JavaWeb项目中加入redis缓存
- Android 调试 Web JavaScript / 微信 Web
- iOS 动画(Animation)总结
- git初级使用
- @staticmethod和@classmethod的用法
- maven导出项目依赖的jar包
- java 8 新特性(2.Lambda表达式)
- 备忘
- Kinect Fusion Basics-WPF C# Sample代码解析
- 注册广播接收者的两种方式
- oracle按照日期字段进行查询/oracle定时任务
- 时间久了不访问站点站点会变得很慢
- 大型网站之分布式会话管理