传送门

  1. https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/Day09/面向对象进阶.md#静态方法和类方法

静态方法@staticmethod

  1. 记得在Fluent Python中大神讲过@staticmethod和普通的函数没什么两样;但是在以下的例子中可以看到,@staticmethod意义在于,这个静态方法和这个类是相关的(虽然这个类的实例对象能调用),但是一般这样设计是给类调用的。
  2. 例子: 我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,**这个方法很显然就不是对象方法**,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以**这个方法是属于三角形类而并不属于三角形对象的**。我们可以使用静态方法来解决这类问题,代码如下所示。
from math import sqrt

class Triangle(object):

    def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c @staticmethod
def is_valid(a, b, c):
return a + b > c and b + c > a and a + c > b # 求周长
def perimeter(self):
return self._a + self._b + self._c # 求面积
def area(self):
# 海伦公式
half = self.perimeter() / 2
return sqrt(half * (half - self._a) *
(half - self._b) * (half - self._c)) def main():
a, b, c = 3, 4, 5
# 静态方法和类方法都是通过给类发消息来调用的
if Triangle.is_valid(a, b, c):
t = Triangle(a, b, c)
print(t.perimeter())
# 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
# print(Triangle.perimeter(t))
print(t.area())
# print(Triangle.area(t))
else:
print('无法构成三角形.') if __name__ == '__main__':
main()

类方法@classmethod

  1. 和静态方法比较类似,Python还可以在类中定义类方法,类方法的第一个参数约定名(convention)为cls,它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),通过这个参数我们可以获取和类相关的信息并且可以创建出类的对象(在@classmethod修饰的函数中return cls()),代码如下所示。
from time import time, localtime, sleep

class Clock(object):
"""数字时钟""" def __init__(self, hour=0, minute=0, second=0):
self._hour = hour
self._minute = minute
self._second = second @classmethod
def now(cls):
current_time = localtime(time())
return cls(current_time.tm_hour, current_time.tm_min, current_time.tm_sec) def run(self):
"""走字"""
self._second += 1
if self._second == 60:
self._second = 0
self._minute += 1
if self._minute == 60:
self._minute = 0
self._hour += 1
if self._hour == 24:
self._hour = 0 def show(self):
"""显示时间"""
return '%02d:%02d:%02d' % \
(self._hour, self._minute, self._second) def main():
# 通过类方法创建对象并获取系统时间
clock = Clock.now()
while True:
print(clock.show())
sleep(1)
clock.run() if __name__ == '__main__':
main()

@staticmethod 和 @classmethod

class Demo():

    @classmethod
def klassmeth(cls, *args):
return args @staticmethod
def statmeth(*args):
return args # 不加cls,退化成@staticmethod
print(Demo.klassmeth()) # ()
print(Demo.klassmeth('spam')) # () print(Demo.klassmeth(Demo,)) # (<class '__main__.Demo'>,)
print(Demo.klassmeth(Demo, 'spam')) # (<class '__main__.Demo'>, 'spam') print(Demo.statmeth()) # ()
print(Demo.statmeth('spam')) # ('spam',)

最新文章

  1. ruby不能识别中文的一个坑
  2. [Spring MVC] - Interceptor 拦截器
  3. select,epoll的比较
  4. 【C#学习笔记】类型转换
  5. CentOS(八)--crontab命令的使用方法
  6. tomcat 配置虚拟路径
  7. Function Pointer in Delpni
  8. c-连接两个链表
  9. HTTP学习笔记3-响应结构
  10. Flex动态获取方法报错
  11. PyTorch常用代码段整理合集
  12. oracle数据库用户基本操作
  13. OSINT系列:威胁信息挖掘ThreatMiner
  14. C#—Dev XtraTabControl操作总结如动态增加Tab和关闭选项卡方法等
  15. 每日英语:How the College Bubble Will Pop
  16. 【代码审计】CLTPHP_v5.5.3 前台任意文件上传漏洞
  17. 搭建Linux-java web运行环境之一:安装jdk+tomcat
  18. PHP获取固定概率
  19. 利用python 下paramiko模块无密码登录
  20. 系统滴答定时器(SysTick)中断配置

热门文章

  1. es2.0的语法学习
  2. layui之普通数据表格显示switch选择表单组件
  3. laravel环境安装
  4. java_细节_windows7下记事本保存为utf-8格式的问题
  5. Linux - Linux中线程为何有PID?
  6. C#堆和栈的入门理解
  7. vue 对象数组中,相邻的且相同类型和内容的数据合并,重组新的数组对象
  8. 整体单改,单局部改,整体局部改,ListSerializer类
  9. glog与gflags的windows编译
  10. HttpClient的CircularRedirectException解决办法