Python的程序结构[1] -> 方法/Method[1] -> 静态方法、类方法和属性方法
静态方法、类方法和属性方法
在 Python 中有三种常用的方法装饰器,可以使普通的类实例方法变成带有特殊功能的方法,分别是静态方法、类方法和属性方法。
静态方法 / Static Method
在 def 定义之前加上 @staticmethod 进行装饰,便可以使该方法成为静态方法,静态方法无法调用实例属性。静态方法可以通过实例或类进行调用。通常用于无需生成实例或无需共享实例属性的方法中,比如一些纯粹的数学公式计算等场合。
class Foo():
@staticmethod
def foo(a, b):
print('This is a staticmethod, cal result: %d' % (a+b)) Foo.foo(1, 2)
Foo().foo(3, 4)
代码中定义了一个简单的 Foo 类,并通过添加静态方法装饰器定义了一个 foo 静态方法,该方法会显示出传入的两个参数的计算结果,由于整个方法中不需要用到实例或实例的属性,因此可以定义为一个静态方法。
This is a staticmethod, cal result: 3
This is a staticmethod, cal result: 7
从输出的结果看到,无论是使用类还是类实例,都可以对静态方法进行调用。
类方法 / Class Method
在 def 定义之前加上 @classmethod 进行装饰,使得该方法成为类方法,类方法同样无法调用实例属性, 但是可以调用类属性,类方法可以通过实例或类进行调用。同时,类方法还可以用于在类实例化之前对类进行一些处理。
class Foo:
num = 1 @classmethod
def instance(cls):
cls.num = 7
cls = cls()
return cls def __init__(self):
self.foo = Foo.num def test(self):
print('This is a test') cls_1 = Foo()
print("foo is: %d, num is: %d" % (cls_1.foo, cls_1.num)) # Change num from 1 to 7 before __init__
cls_2 = Foo.instance()
print("foo is: %d, num is: %d" % (cls_2.foo, cls_2.num))
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 装饰的同名方法,在这个方法内实现对属性方法返回值的修改。
class Foo(object):
def __init__(self):
self._foo = None
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
if isinstance(value, int):
self._foo = (value + 0.5)
if __name__ == "__main__":
f = Foo()
print("foo is %s" % f.foo)
f.foo = 1
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 当做是一个属性赋值即可)。
相关阅读
1. 装饰器
Python的程序结构[1] -> 方法/Method[1] -> 静态方法、类方法和属性方法的更多相关文章
- Python的程序结构[2] -> 类/Class[0] -> 类的特殊属性
类的特殊属性 / Special Property of Class Python 中通过 class 进行类的定义,类可以实例化成实例并利用实例对方法进行调用. 类中还包含的一些共有的特殊属性. 特 ...
- Python 静态方法、类方法和属性方法
Python 静态方法.类方法和属性方法 静态方法(staticmethod) staticmethod不与类或者对象绑定,类和实例对象都可以调用,没有自动传值效果,Python内置函数staticm ...
- Python面向对象静态方法,类方法,属性方法
Python面向对象静态方法,类方法,属性方法 属性: 公有属性 (属于类,每个类一份) 普通属性 (属于对象,每个对象一份) 私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法: ...
- 【面试必问】python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别
[面试必问]python实例方法.类方法@classmethod.静态方法@staticmethod和属性方法@property区别 1.#类方法@classmethod,只能访问类变量,不能访问实例 ...
- python中静态方法、类方法、属性方法区别
在python中,静态方法.类方法.属性方法,刚接触对于它们之间的区别确实让人疑惑. 类方法(@classmethod) 是一个函数修饰符,表是该函数是一个类方法 类方法第一个参数是cls,而实例方法 ...
- Python笔记_第四篇_高阶编程_实例化方法、静态方法、类方法和属性方法概念的解析。
1.先叙述静态方法: 我们知道Python调用类的方法的时候都要进行一个实例化的处理.在面向对象中,一把存在静态类,静态方法,动态类.动态方法等乱七八糟的这么一些叫法.其实这些东西看起来抽象,但是很好 ...
- Python的程序结构[1] -> 方法/Method[0] -> 类实例方法、私有方法和抽象方法
类实例方法.私有方法和抽象方法 Python中最常用的就是类实例方法,类似于属性中的类实例属性,同时,也存在与私有属性类似方法,即私有方法,下面介绍这两种常见的方法,以及一种特殊意义的类实例方法 -- ...
- Python的程序结构[1] -> 方法/Method[2] -> 魔术方法 __init__ / __del__ / __new__
魔术方法 / Magic Method 魔法方法就是可以给你的类增加魔力的特殊方法(实质应称为特殊方法,魔术方法在JavaScript中有所体现,对象具有不透明特性,而且无法在自定义对象中模拟这些行为 ...
- Python的程序结构[1] -> 方法/Method[3] -> 魔术方法 __getattr__ 与代理模式
__getattr__ 方法 __getattr__ 方法当对象调用内部属性(包括方法等)且未找到对应属性的时候会调用的特殊方法.利用这一特性,可是对函数实现一个代理模式. __getattr__方法 ...
随机推荐
- 【Perceptron Learning Algorithm】林轩田机器学习基石
直接跳过第一讲.从第二讲Perceptron开始,记录这一讲中几个印象深的点: 1. 之前自己的直觉一直对这种图理解的不好,老按照x.y去理解. a) 这种图的每个坐标代表的是features:fea ...
- linux驱动学习_1
目前项目需要,需要做linux驱动了,记录一下 学习驱动,大家一定都会写一个hello world代码,网上也有很多范例,但是记录一下遇到的问题. 1.make之后,使用insmod加载,终端没有打印 ...
- Python 模块:random 随机数生成
Python中的random模块用于生成随机数. 使用该模块之前需要 import random 几个常用的函数用法: 1.random.random 函数原型: random.random() 用于 ...
- flask利用session身份伪造
想研究很久了,这次终于初步了解了flask session伪造(得知道密钥). python2和python3 session解密不一样,而且不都是base64,脚本https://github.co ...
- python的inspect模块
一.type and members 1. inspect.getmembers(object[, predicate]) 第二个参数通常可以根据需要调用如下16个方法: 返回值为object的所有成 ...
- linux系统下怎么关闭一个端口
netstat -an | grep 22查看22端口 netstat -ntulp |grep 80 //查看所有80端口使用情况
- Opencv3.0.0安装包
这个资源是Opencv3.0.0安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载
- java的四种内部类(转)
一般来说,有4中内部类:常规内部类.静态内部类.局部内部类.匿名内部类. 一.常规内部类:常规内部类没有用static修饰且定义在在外部类类体中. 1.常规内部类中的方法可以直接使用外部类的实例变量 ...
- A Neural Algorithm of Artistic Style
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/53931536 1. 资源 Paper: ...
- jQuery静态分页功能
分页功能在做项目的过程中是常常用到的,下面是我常用的一款分页效果: 1.分页的CSS样式(page.css) #setpage { margin: 15px auto; text-align: cen ...