重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
python的类里用@staticmethod的是静态方法,@classmethod的是类方法,如下
成都创新互联2013年开创至今,先为香坊等服务建站,香坊等地企业,进行企业商务咨询服务。为香坊企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
class Person(object):
person_list = []
def __init__(self, name, age):
self.name = name
self.age = age
self.person_list.append(self)
@classmethod
def one_year_later(cls):
for p in cls.person_list:
p.age += 1
@staticmethod
def born_one_boby(name):
return Person(name, 0)
def __repr__(self):
return 'Person name:%s, age:%s' % (self.name, self.age)
if __name__ == '__main__':
petter = Person('Petter',23)
merry = Person('Merry',21)
print(petter) # Person name:Petter, age:23
print(merry) # Person name:Merry, age:21
Person.one_year_later()
print(petter) # Person name:Petter, age:24
print(merry) # Person name:Merry, age:22
baby = merry.born_one_boby('Tom')
print(Person.person_list) # [Person name:Petter, age:24, Person name:Merry, age:22, Person name:Tom, age:0]
在学习python代码时,看到有的类的方法中第一参数是cls,有的是self,经过了解得知,python并没有对类中方法的第一个参数名字做限制,可以是self,也可以是cls,不过根据人们的惯用用法,self一般是在实例方法中使用,而cls则一般在类方法中使用,在静态方法中则不需要使用一个默认参数。在下面的代码中,InstanceMethod类的方法中,第一个参数是默认的self,在这里可以把self换成任何名字来表示,不会有任何影响。在类调用的时候,需要满足参数的个数要求(参数中含有*args是例外),例如13行中,类调用没有参数的时候,会提示错误。同样,实例方法的参数个数也应该满足要求,例如16行中也会报错。实例方法的一个主要特点就是需要绑定到一个对象上,python解析器会自动把实例自身传递给方法,如14行所示,而直接使用InstanceMethod.f1()调用方法是不行的。
12345678910111213
class InstanceMethod(object): def __init__(self, a): self.a = a def f1(self): print 'This is {0}.'.format(self) def f2(self, a): print 'Value:{0}'.format(a)if __name__ == '__main__': # im = InstanceMethod() im = InstanceMethod('233') im.f1() # im.f2() im.f2(233)
静态方法和类方法都需要使用修饰器,分别使用的是staticmethod和classmethod。静态方法是和类没有关系的,我觉得就是包装在类中的一般方法,如下例子中,调用静态方法使用实例和不使用实例都是可以的。类方法中,默认的第一个参数使用的是cls,类方法也可以不需要实例而直接使用类调用。对于这三种不同的方法,使用方法如下例所示。那么问题来了,既然有了实例方法,类方法和静态方法与之相比又有什么好处呢?
在类方法中,不管是使用实例还是类调用方法,都会把类作为第一个参数传递进来,这个参数就是类本身。如果继承了这个使用类方法的类,该类的所有子类都会拥有了这个方法,并且这个方法会自动指向子类本身,这个特性在工厂函数中是非常有用的。静态方法是和类与实例都没有关系的,完全可以使用一般方法代替,但是使用静态方法可以更好的组织代码,防止代码变大后变得比较混乱。类方法是可以替代静态方法的。静态方法不能在继承中修改。
123456789101112131415161718
class test(object): def instance_method(self): print 'This is {0}'.format(self) @staticmethod def static_method(): print 'This is static method.' @classmethod def class_method(cls): print 'This is {0}'.format(cls)if __name__ == '__main__': a = test() a.instance_method() a.static_method() a.class_method() print '----------------------------------------' # test.instance_method() test.static_method() test.class_method()
@staticmethod 静态方法只是名义上归属类管理,但是 不能使用类变量和实例变量,是类的工具包
放在函数前(该函数不传入self或者cls),所以不能访问类属性和实例属性
1
2
3
4
5
6
7
8
9
10
11
12
13
class A(object):
def fun_a(self):#实例方法
pass
@staticmethod
def fun_b():#静态方法
pass
@classmethod
def fun_c(cls):#类方法
pass
虽然静态方法和类方法调用方式都一样,都可以通过【类.方法名】来使用,但是类方法中有默认属性cls,指向自身的类,所以一般如果是单一的工具函数定义成静态方法,如果还需要调用类中其他的静态方法,或者类方法的函数定义成类方法。望采纳。
面相对象程序设计中,类方法和静态方法是经常用到的两个术语。
逻辑上讲:类方法是只能由类名调用;静态方法可以由类名或对象名进行调用。
在C++中,静态方法与类方法逻辑上是等价的,只有一个概念,不会混淆。
而在python中,方法分为三类实例方法、类方法、静态方法。代码如下:
class Test(object):
def InstanceFun(self):
print("InstanceFun");
print(self);
@classmethod
def ClassFun(cls):
print("ClassFun");
print(cls);
@staticmethod
def StaticFun():
print("StaticFun");
t = Test();
t.InstanceFun();# 输出InstanceFun,打印对象内存地址“__main__.Test object at 0x0293DCF0”
Test.ClassFun(); # 输出ClassFun,打印类位置 class '__main__.Test'
Test.StaticFun(); # 输出StaticFun
t.StaticFun(); # 输出StaticFun
t.ClassFun(); # 输出ClassFun,打印类位置 class '__main__.Test'
Test.InstanceFun(); # 错误,TypeError: unbound method instanceFun() must be called with Test instance as first argument
Test.InstanceFun(t); # 输出InstanceFun,打印对象内存地址“__main__.Test object at 0x0293DCF0”
t.ClassFun(Test); # 错误 classFun() takes exactly 1 argument (2 given)
可以看到,在python中,两种方法的主要区别在于参数。实例方法隐含的参数为类实例self,而类方法隐含的参数为类本身cls。
静态方法无隐含参数,主要为了类实例也可以直接调用静态方法。
所以逻辑上类方法应当只被类调用,实例方法实例调用,静态方法两者都能调用。主要区别在于参数传递上的区别,实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是cls引用作为参数。
python实现了一定的灵活性使得类方法和静态方法,都能够被实例和类二者调用
Python使用函数默认值实现函数静态变量的方法,具体方法如下:
一、Python函数默认值
Python函数默认值的使用可以在函数调用时写代码提供方便,很多时候我们只要使用默认值就可以了。 所以函数默认值在python中用到的很多,尤其是在类中间,类的初始化函数中一帮都会用到默认值。 使用类时能够方便的创建类,而不需要传递一堆参数。
只要在函数参数名后面加上 ”=defalut_value”,函数默认值就定义好了。有一个地方需要注意的是,有默认值的参数必须在函数参数列表的最后,不允许将没有默认值的参数放在有默认值的参数后,因为如果你那样定义的话,解释器将不知道如何去传递参数。
先来看一段示例代码:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return True
if ok in ('n', 'no', 'nop', 'nope'): return False
retries = retries - 1
if retries 0: raise IOError, 'refusenik user'
print complaint
你调用上面的函数时,可以修改重试次数和输出的提示语言,如果你比较懒得话,那么什么都不用改。
二、python使用函数默认值来实现函数静态变量的功能
Python中是不支持静态变量的,但是我们可以通过函数的默认值来实现静态变量的功能。
当函数的默认值是内容是可变的类时,类的内容可变,而类的名字没变。(相当于开辟的内存区域没有变,而其中内容可以变化)。
这是因为python中函数的默认值只会被执行一次,(和静态变量一样,静态变量初始化也是被执行一次。)这就是他们的共同点。
再来看下面的程序片段:
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
print f(4,['x'])
print f(5)
其输出结果是:
[1]
[1, 2]
[1, 2, 3]
['x', 4]
[1, 2, 3, 5]
前面的好理解,为什么最后 “print f(5)”的输出是 “[1, 2, 3, 5]”呢?
这是因为 “print f(4,['x'])”时,默认变量并没有被改变,因为默认变量的初始化只是被执行了一次(第一次使用默认值调用),初始化执行开辟的内存区(我们可以称之为默认变量)没有被改变,所以最后的输出结果是“[1, 2, 3, 5]”。