Python的程序结构(2) -> 方法/Method -> 静态方法、类方法和属性方法

静态方法、类方法和属性方法



在 Python 中有三种常用的方法装饰器(参考装饰器部分内容),可以使普通的类实例方法变成带有特殊功能的方法,分别是静态方法、类方法和属性方法。

静态方法 / Static Method



在 def 定义之前加上 @staticmethod 进行装饰,便可以使该方法成为静态方法,静态方法无法调用实例属性。静态方法可以通过实例进行调用。通常用于无需生成实例或无需共享实例属性的方法中,比如一些纯粹的数学公式计算等场合。

1 class Foo():
2     @staticmethod
3     def foo(a, b):
4         print(‘This is a staticmethod, cal result: %d‘ % (a+b))
5
6 Foo.foo(1, 2)
7 Foo().foo(3, 4)

代码中定义了一个简单的 Foo 类,并通过添加静态方法装饰器定义了一个 foo 静态方法,该方法会显示出传入的两个参数的计算结果,由于整个方法中不需要用到实例或实例的属性,因此可以定义为一个静态方法。

This is a staticmethod, cal result: 3
This is a staticmethod, cal result: 7

从输出的结果看到,无论是使用类还是类实例,都可以对静态方法进行调用。

类方法 / Class Method



在 def 定义之前加上 @classmethod 进行装饰,使得该方法成为类方法,类方法同样无法调用实例属性, 但是可以调用类属性,类方法可以通过实例进行调用。同时,类方法还可以用于在类实例化之前对类进行一些处理。

 1 class Foo:
 2     num = 1
 3
 4     @classmethod
 5     def instance(cls):
 6         cls.num = 7
 7         cls = cls()
 8         return cls
 9
10     def __init__(self):
11         self.foo = Foo.num
12
13     def test(self):
14         print(‘This is a test‘)
15
16 cls_1 = Foo()
17 print("foo is: %d, num is: %d" % (cls_1.foo, cls_1.num))
18
19 # Change num from 1 to 7 before __init__
20 cls_2 = Foo.instance()
21 print("foo is: %d, num is: %d" % (cls_2.foo, cls_2.num))
22 cls_2.test()

上面的代码中,定义了一个类方法,这个类方法会在调用的时候修改 Foo 类的 num 属性,随后在生成一个类实例(第 7 行,这步实际上完成了一个类的初始化)并返回。首先不调用类方法,直接生成一个类实例 cls_1,随后查看 cls_1 中的属性值,然后在利用类方法,通过 Foo 直接调用 instance 方法生成一个类实例 cls_2,并同样的查看类实例中的属性,最后调用 test 方法来测试这个类实例是否可以和正常生成的类实例一样调用实例方法。

foo is: 1, num is: 1
foo is: 7, num is: 7
This is a test

最后的输出结果可以看出,直接生成的类实例 cls_1 中的属性并没有被改变,而通过类实例方法生成的类实例 cls_2 中的属性则变化了,同时这个 cls_2 也同样能够调用普通的实例方法。也就是说类方法可以通过类进行直接调用而不需要先经过实例化,同时类方法传入的第一个参数 cls 即为当前的类
Note: 这种类方法可以用在单例模式(参考单例模式)中,确保一个类无论实例化多少次都只有一个实例对象存在。

属性方法 / Property Method



在 def 定义之前加上 @property 进行装饰,使得该方法成为属性方法,属性方法可以在外部像调用属性一样直接进行调用,若需要实现对属性方法值的修改,则还需要定义由 @methodname.setter 装饰的同名方法,在这个方法内实现对属性方法返回值的修改。

 1 class Foo(object):
 2
 3     def __init__(self):
 4         self._foo = None
 5
 6     @property
 7     def foo(self):
 8         return self._foo
 9
10     @foo.setter
11     def foo(self, value):
12         if isinstance(value, int):
13             self._foo = (value + 0.5)
14
15 if __name__ == "__main__":
16     f = Foo()
17     print("foo is %s" % f.foo)
18     f.foo = 1
19     print("foo is %s" % f.foo)

上面的代码中定义了一个 foo 的属性方法和属性方法的 setter,这样就是的 foo 这个方法使用起来就如同是一个属性一般,可以直接通过实例进行调用(第17 / 19 行),而 @foo.setter 装饰器也赋予了 foo 属性方法赋值的能力,可以通过类似属性赋值的方式直接给 foo 传递一个参数(第 18 行),并且此时还可以对这个传入的参数进行一定的操作(如第 12 / 13 行)。

foo is None
foo is 1.5

最终输出的结果中可以看出,foo 虽然是一个方法,但是其使用的方式却完全类似于一个属性,这中属性方法所提供的功能在面向对象编程的时候十分有效,常常可以通过定义好属性方法来实现一系列对象的操作,使得一个实例更加接近真实对象的行为方式(上面的例子可能不算十分恰当,不过可以理解为一个识别器,只要传入的是数字,便修改自身的 _foo 属性为该值+0.5,而在外部则无需关心这一实现,只把 foo 当做是一个属性赋值即可)。

时间: 2024-12-10 12:10:30

Python的程序结构(2) -> 方法/Method -> 静态方法、类方法和属性方法的相关文章

Python的程序结构[2] -> 类/class -> 类的特殊属性

类的特殊属性 / Special Property of Class Python 中通过 class 进行类的定义,类可以实例化成实例并利用实例对方法进行调用. 类中还包含的一些共有的特殊属性. 特殊类属性 含义 __name__ 类的名字(字符串) __doc__ 类的文档字符串 __bases__ 类的所有父类组成的元组 __dict__ 类的属性组成的字典 __module__ 类所属的模块 __class__ 类对象的类型 1 class Foo(): 2 """

python中静态方法、类方法、属性方法区别

在python中,静态方法.类方法.属性方法,刚接触对于它们之间的区别确实让人疑惑. 类方法(@classmethod) 是一个函数修饰符,表是该函数是一个类方法 类方法第一个参数是cls,而实例方法第一个参数是self(表示该类的一个实例) 类中普通函数至少要一个self参数,代表类对象实例 类方法至少需要一个cls参数,通过cls可以获取到类本身的属性方法等元信息.当有个子类继承时,传入的是子类对象. 对于类方法两种调用方式,类.func(),类实例.func() 静态方法(@staticm

python:静态方法、类方法、属性方法

静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. 例子: class dog(object):----def init(self,name):br/>--------self.name=name[email protected]----def eat(self):--------print("%s is eating" %self.name,"baozi")d=dog("small")d.eat(d) 类方法:

js中__proto__, property, prototype, 对象自身属性方法和原型中的属性方法的区别

__proto__: 这个属性是实例对象的属性,每个实例对象都有一个__proto__属性,这个属性指向实例化该实例的构造函数的原型对象(prototype). proterty:这个方法是对象的属性.(据说和一个对象的attr类似,比如dom对象中) prototype:每个构造函数都有一个prototype对象,这个对象指向该构造函数的原型. 对象自身属性方法和原型中的属性方法的区别: 对象自身的属性和方法只对该对象有效,而原型链中的属性方法对所有实例有效. 例子: function bas

python学习第七周之静态方法、类方法、属性方法和一些类的成员方法

1.静态方法:只是名义上归类来管理,实际上在静态方法访问不了类或实例中的任何属性. (1)我们先看以下代码,实例化一个对象后,d可以直接调用talk() class Dog(object): def __init__(self,name): self.name=name def talk(self): print("%s is talking" % self.name) d=Dog("chen") d.talk() (2)而我们在使用静态方法后,实例化后直接调用的话

python第三十三天----静态方法、类方法、属性方法

@staticmethod 装饰后,类中的方法转成静态方法 1 class a: 2 3 @staticmethod 4 def b(self): 5 print('') 静态方法不可以访问实例变量或类变量,相当于类中的工具包.如os,  system 等 import的模块一般 @classmethod装饰后,类中的方法转成类方法,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量 1 class b(object): 2 name='aa' 3 @classmethod 4

Python面向对象静态方法,类方法,属性方法

静态方法(staticmethod名义上归类管理,实际上在静态方法里访问不到类或实例中的静态属性) 1 class days(object): 2 def __init__(self, food): 3 self.food = food 4 5 @staticmethod # 实际和类没有关系 6 def tell(self): 7 print('这里有%s,%s快来' % (self.food, 'name')) 8 9 10 a = days('香蕉') 11 a.tell(a) 类方法(c

Python学习——静态方法、类方法、属性方法

import os # os.system() # os.mkdir() class Dog(object): # name = 'kk' def __init__(self,name): self.name = name # @staticmethod #静态方法,实际上跟类没什么关系了,并且,这个不会主动传self参数的. # @classmethod #类方法,能够调用self参数了,但是不能够调用实例化的变量. @property #静态属性,不能传入参数了,只能自己调用类或者实例里面的

python学习笔记之面向对象中的静态方法、类方法、属性方法总结

静态方法 类方法 属性方法 一.静态方法 可以利用@staticmethod装饰器把一个方法变成一个静态方法.静态方法不可以方法实例变量或者类变量,也就是说不可以使用self.属性这样子调用实例属性了.其实静态方法就和类本身没什么关系了,它和类 唯一的关联就是需要通过类名来调用这个方法. 错误调用方式: class Dog(object): def __init__(self,name): self.name = name @staticmethod #把eat方法变为静态方法 def eat(