Python3学习之路~7.1 静态方法、类方法、属性方法
静态方法
通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。
下面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。
class Dog(object):
def __init__(self,name):
self.name = name @staticmethod #静态方法
def eat(self):
print("%s is eating" % self.name ) d = Dog("小黄")
d.eat() #报错:TypeError: eat() missing 1 required positional argument: 'self'
想让上面的代码可以正常工作有两种办法
1. 调用时主动传递实例本身给eat方法,即d.eat(d) 。但是这样做没有意义,你都把自己传进去了,为什么还要写静态方法呢?
2. 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了。
class Dog(object):
def __init__(self,name):
self.name = name @staticmethod #静态方法
def eat():
print("is eating" ) d = Dog("小黄")
d.eat()
静态方法在实际场景中的应用:你可以将静态方法理解为类的工具包。比如
import os
os.system()
os.mkdir()
system()与mkdir()完全没有关系,os就相当于一个工具包组合,将很多函数组合在一起,函数和函数之间不需要通过self相互调用,此时你就可以把system()和mkdir()变成静态方法。静态方法是一种高级语法,在某些特定场景下你可能用得到,但是在大多数情况下其实是用不到的。
类方法
类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。
执行如下代码报错说Dog没有name属性,因为name是个实例变量,类方法是不能访问实例变量的
class Dog(object):
def __init__(self,name):
self.name = name @classmethod #类方法
def eat(self):
print("%s is eating" % self.name ) d = Dog("小黄")
d.eat() #报错:AttributeError: type object 'Dog' has no attribute 'name'
此时可以定义一个类变量,也叫name,看下执行效果
class Dog(object):
name = "我是类变量"
def __init__(self,name):
self.name = name @classmethod #类方法
def eat(self):
print("%s is eating" % self.name ) d = Dog("小黄")
d.eat() #执行结果:我是类变量 is eating
属性方法
属性方法的作用就是通过@property装饰器把一个方法变成一个静态属性
class Dog(object):
def __init__(self,name):
self.name = name @property #属性方法
def eat(self):
print("%s is eating" % self.name ) d = Dog("小黄")
d.eat() #报错:TypeError: 'NoneType' object is not callable
调用会出以上错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了,想调用已经不需要加()号了,直接d.eat就可以了
d = Dog("小黄")
d.eat #执行结果:小黄 is eating
既然eat已经成为一个静态属性了,那么是否可以为其重新赋值呢?试一试
d = Dog("小黄")
d.eat
d.eat="baozi" #报错:AttributeError: can't set attribute
输出说不能更改这个属性怎么办?
当然可以改, 不过需要通过@eat.setter装饰器再装饰一下,此时你需要写一个新eat方法, 对这个eat进行更改。
class Dog(object):
def __init__(self,name):
self.name = name @property #属性方法
def eat(self):
print("%s is eating" % self.name ) @eat.setter
def eat(self,food):
print("set to food" ,food ) d = Dog("小黄")
d.eat
d.eat="baozi" #输出:set to food baozi
d.eat # 输出:小黄 is eating
你可以看到,虽然eat被重新赋值了,但是当再次打印d.eat时,输出的结果还是没变。这是因为eat此时保存的是一系列动作,并没有保存结果。如果想要将结果保存,可以再定义一个属性。如下你可以看到,可以为eat传参数了。
class Dog(object):
def __init__(self,name):
self.name = name
self.__food = None @property #属性方法
def eat(self):
print("%s is eating" % self.name,self.__food ) @eat.setter
def eat(self,food):
self.__food = food d = Dog("小黄")
d.eat="baozi"
d.eat # 输出:小黄 is eating baozi
那么这个属性方法可以删除吗?试一试
d = Dog("小黄")
d.eat="baozi"
d.eat # 输出:小黄 is eating baozi
del d.eat #输出:AttributeError: can't delete attribute
输出报错说不能删除这个属性怎么办?
当然可以删除,不过需要通过@eat.deleter装饰器再装饰一下,此时你需要写一个新eat方法, 对这个eat进行更改。
class Dog(object):
def __init__(self,name):
self.name = name
self.__food = None @property #属性方法
def eat(self):
print("%s is eating" % self.name,self.__food ) @eat.setter
def eat(self,food):
self.__food = food @eat.deleter
def eat(self):
del self.__food
print("删除成功") d = Dog("小黄")
d.eat="baozi"
d.eat # 输出:小黄 is eating baozi del d.eat #输出:删除成功
# d.eat #删完再次调用报错:AttributeError: 'Dog' object has no attribute '_Dog__food'
好吧,把一个方法变成静态属性有什么用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:
1. 连接航空公司API查询
2. 对查询结果进行解析
3. 返回结果给你的用户
因此这个flight_status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?
class Flight(object):
def __init__(self,name):
self.flight_name = name def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1 @property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("flight got canceled...")
elif status == 1 :
print("flight is arrived...")
elif status == 2:
print("flight has departured already...")
else:
print("cannot confirm the flight status...,please check later") f = Flight("CA980")
f.flight_status # 输出:
# checking flight CA980 status
# flight is arrived...
航班查询
当然我们也可以对flight_status进行修改和删除
class Flight(object):
def __init__(self,name):
self.flight_name = name def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1 @property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("flight got canceled...")
elif status == 1 :
print("flight is arrived...")
elif status == 2:
print("flight has departured already...")
else:
print("cannot confirm the flight status...,please check later") @flight_status.setter #修改
def flight_status(self,status):
status_dic = {
: "canceled",
:"arrived",
: "departured"
}
print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) ) @flight_status.deleter #删除
def flight_status(self):
print("status got removed...") f = Flight("CA980")
f.flight_status
f.flight_status = 2 #触发@flight_status.setter
del f.flight_status #触发@flight_status.deleter
Python3学习之路~7.1 静态方法、类方法、属性方法的更多相关文章
- python静态方法类方法属性方法
Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的: 1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数: 2)从第1条,静态方法是无法访问 ...
- Python3学习之路~0 目录
目录 Python3学习之路~2.1 列表.元组操作 Python3学习之路~2.2 简单的购物车程序 Python3学习之路~2.3 字符串操作 Python3学习之路~2.4 字典操作 Pytho ...
- mybatis学习之路----批量更新数据两种方法效率对比
原文:https://blog.csdn.net/xu1916659422/article/details/77971696/ 上节探讨了批量新增数据,这节探讨批量更新数据两种写法的效率问题. 实现方 ...
- Python3学习之路~8.5 SocketServer实现多并发
前面几节我们写的socket都只能实现服务端与一个客户端通信,并不能实现服务端与多客户端同时通信.接下来我们就来学习一下如何实现服务端同时与多个客户端通信,即并发. Socket Server soc ...
- Python3学习之路~3.3 内置函数
Python内置函数表: 内置参数详解:https://docs.python.org/3/library/functions.html?highlight=built#ascii 用法: #Auth ...
- Python3学习之路~9.4 队列、生产者消费者模型
一 队列queue 当必须在多个线程之间安全地交换信息时,队列在线程编程中特别有用. 队列的作用:1.解耦,使程序直接实现松耦合 2.提高处理效率 列表与队列都是有顺序的,但是他们之间有一个很大的区别 ...
- Python3学习之路~9.1 paramiko模块:实现ssh执行命令以及传输文件
我们一般使用linux的时候,都是在Windows上安装一个ssh客户端连接上去.那么从一台linux如何连接到另一条linux呢?使用ssh命令即可,因为每台linux机器自己都有一个ssh客户端. ...
- Python3学习之路~8.6 开发一个支持多用户在线的FTP程序-代码实现
作业: 开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp s ...
- Python3学习之路~8.4 利用socket实现文件传送+MD5校验
利用socket实现文件传送,大约分为如下几步: 1.读取文件名2.检测文件是否存在3.打开文件(别忘了最后关闭文件)4.检测文件大小5.发送文件大小给客户端6.等客户端确认7.开始边读边发数据8.m ...
随机推荐
- webpack4 搭建遇到的奇葩问题集合
一.webpack4 打包es6 会报错 需要安装一下插件 https://blog.csdn.net/Beamon__/article/details/85048448二.webpack4 打包动态 ...
- 【自然语言处理】LDA
飞机票 飞机票 步骤: 1. 离线求的模型 2. 用模型对新文本预测topic,取topic概率带到阈值(例如0.2)且topN个topic,例如doc1 :topic1:0.5, topic2:0. ...
- 数位dp-入门模板题 hdu2089
#include<bits/stdc++.h> using namespace std; ][],n,m; void init(){//dp[i][j]:i位的数,最高位是j dp[][] ...
- 【工具】idea工具 java代码 gbk转utf8
idea工具 https://github.com/downgoon/gbk2utf8 安装在目录下: /usr/local/gbk2utf8/bin 进入目录后直接执行 gbk2utf8 sourc ...
- bootstrap selectpicker控件select下拉框动态数据无法回显的问题
有关于selectpicker下拉框数据回显的问题,当查看一个对象的属性的时候, 发现有关于selectpicker的下拉框并没有将返回的数据进行回显,显示的都是请选择, 经查证,当查看属性的时候,他 ...
- BZOJ4451 [Cerc2015]Frightful Formula 多项式 FFT 递推 组合数学
原文链接http://www.cnblogs.com/zhouzhendong/p/8820963.html 题目传送门 - BZOJ4451 题意 给你一个$n\times n$矩阵的第一行和第一列 ...
- js查找字符串、js截取
js查找元素.js查找字符串 let index=data.indexOf(","); js截取.js截取字符串 $("#bankurl_id").val(da ...
- twig模板基本学习
twig基本语法 1.输出 {{ }} 2.判断 {% %} 3.注释 {# #} 具体使用时参考https://twig.symfony.com/doc/2.x/官网文档进行查 ...
- DDoS攻击与防御(3)
3.攻击应用资源网络应用和服务在处理数据时,通常需要消耗一定的网络连接.计算和存储资源,这些资源是由应用程序向系统进行申请并自行管理和维护的.消耗应用资源的DDoS攻击就是通过向应用提交大量消耗资源的 ...
- Beta(2/7)
鐵鍋燉腯鱻 项目:小鱼记账 团队成员 项目燃尽图 冲刺情况描述 站立式会议照片 各成员情况 团队成员 学号 姓名 git地址 博客地址 031602240 许郁杨 (组长) https://githu ...