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 ...
随机推荐
- python开发环境_windows系统安装_错误记录
1 安装python编译器2.7.11版本 (安装包自带pip,setuptools,依赖,会将pip,setuptools安装到自己的类库中) 配置环境变量: 配置python_home,然后加入p ...
- Maven mvn install 本地jar添加到本地maven仓库中
mvn install:install-file -DgroupId=alipay -DartifactId=taobao-sdk-java-auto -Dversion=1.0 -Dpackagin ...
- pycharm中连接公网IP方法
我们的公网IP可以加到pycharm里面,这样程序跑的时候,在测试过程中就用pycharm直接修改文件,然后在pycharm里面上传,操作更加便捷 在pycharm中找到tool按钮,在菜单栏里面 然 ...
- Android高级工程师面试实战,您会挂么?
xxx公司面试总结 面试形势 群聊(2个面试官+HR+自己) 面试流程 自我介绍 面试官根据你的介绍开始问 你对我们公司有什么想了解的么(复活卡,要时回到没有了也就没有了,可以让面试官给自己提一下建议 ...
- 提升webpack打包速度
webpack打包文件体积过大,怎么提升速度? 借助webpack visualizer可视化插件,来看构建的情况.这个问题要具体情况具体分析,看看打包文件有哪些块头比较大,哪些不常改变,最好列一个l ...
- 2019-2-14SQLserver中拼音查询数据
SQLserver中获取文字的全拼音: CREATE function [dbo].[f_GetPinyin](@words nvarchar()) returns varchar() as begi ...
- SDOI2019 省选前模板整理
目录 计算几何✔ DP 斜率优化✔ 四边形不等式✔ 轮廓线DP✘ 各种分治 CDQ分治✔ 点分治✔ 整体二分✔ 数据结构 线段树合并✔ 分块✔ K-D Tree LCT 可持久化Trie✔ Splay ...
- 友元(friend)
1.友元类的关系不能传递和继承 ...待续
- S0.2 灰度图
目录 灰度图定义 灰度图优点 RGB转灰度算法(OpenCV3) 量化 算法公式 OpenCV自带函数实现 综合比较 灰度图定义 对于单色(灰度)图像而言,每个像素的亮度用一个数值来表示,通常数值范围 ...
- 11 安装已集成HA的树莓派镜像Hassbian
2017-09-04 10:40:47 下载Hassbian镜像文件,浏览https://github.com/home-assistant/pi-gen/releases/tag/v1.23,查看最 ...