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__方法 ...
随机推荐
- 《Cracking the Coding Interview》——第18章:难题——题目13
2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3 ...
- Python全栈 MySQL 数据库 (简述 、安装、基本命令)
ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 为了梦想为了信仰 开局一张图 一个月的python已经结束了 下面就是数据库了 先说M ...
- Struts2+DAO层实现实例03——添加监听器跟踪用户行为
实例说明 根据上两次的成品进行二次加工. 加入Listener,监听用户的登陆注销情况. 所用知识说明 采用SessionBindingListener对Session进行监听. 同时,Action中 ...
- android 远程Service以及AIDL的跨进程通信
在Android中,Service是运行在主线程中的,如果在Service中处理一些耗时的操作,就会导致程序出现ANR. 但如果将本地的Service转换成一个远程的Service,就不会出现这样的问 ...
- CodeForces Round #515 Div.3 C. Books Queries
http://codeforces.com/contest/1066/problem/C You have got a shelf and want to put some books on it. ...
- jQuery选择器之元素选择器
元素选择器:根据给定(html)标记名称选择所有的元素. 描述: $('element') 搜索指定元素标签名的所有节点,这是一个合集的操作.同样的也有原生方法getElementsByTagName ...
- select chosen 禁用下拉框某一个option
$("#tbParBudCode option[value='" + budCodeId + "']").attr("disabled", ...
- 学习go语言第一天
今天先下载了go语言,FQ去下载的,一开始想用eclipse,然后下载了go插件,结果出现错误,我英语水平有限,就换了liteIDE,感觉还不错,go语言环境变量因为我是msi安装的,好像可以不用自己 ...
- Arcgis桌面开发,Python引用GDAL库的方法
我用的是arcgis10.2,python版本是arcgis自动安装的Pythin2.7 1.下载gdal-111-1700-core.msi和对应的GDAL-1.11.1.win32-py2.7.m ...
- NetScaler的cookieinsert和sourceip联合保持机制
NetScaler的cookieinsert和sourceip联合保持机制 使用NetScaler的cookieinsert和sourceip联合进行session保持机制即主用cookieinser ...