day26:装饰器&面向对象当中的方法&property
目录
装饰器
1.装饰器 : 为原函数去扩展新功能,用新函数去替换旧函数
2.作用 : 在不改变原代码的前提下,实现功能上的扩展
3.符号 : @(语法糖)
1.装饰器的基本用法
# 1.装饰器的基本用法
'''装饰器是基于闭包函数来实现的'''
def kuozhan(func):
def newfunc():
print("厕所前,蓬头垢面")
func()
print("厕所后,精神抖擞")
return newfunc def func():
print("我是宋云杰") '''kuozhan()的返回值是newfunc,newfunc替换了func'''
func = kuozhan(func) # func = newfunc
'''所以调用func就是相当于在调用newfunc'''
func() # newfunc()
2.@符号的使用
@符号作用:
(1) 可以自动把@符号下面的函数当成参数传递给装饰器
(2) 把新函数返回,让新函数去替换旧函数,以实现功能上的扩展(基于原函数)
# 2.@符号的使用
"""
@符号作用:
(1) 可以自动把@符号下面的函数当成参数传递给装饰器
(2) 把新函数返回,让新函数去替换旧函数,以实现功能上的扩展(基于原函数)
""" def kuozhan(func):
def newfunc():
print("厕所前,牛头马面")
func()
print("厕所后,黑白无常")
return newfunc '''1.把func当做参数传递给装饰器kuozhan'''
'''2.将新函数newfunc返回替换旧函数func,进而实现功能的扩展'''
@kuozhan
def func():
print("我是高雪峰")
func()
3.装饰器的嵌套

# 3.装饰器的嵌套
def kuozhan1(func):
def newfunc():
print("厕所前,人模狗样1")
func()
print("厕所后,斯文败类2")
return newfunc def kuozhan2(func):
def newfunc():
print("厕所前,洗洗手3")
func()
print("厕所后,簌簌口4")
return newfunc @kuozhan2
@kuozhan1
def func():
print("我是葛龙0") func()
4.用装饰器扩展带有参数的原函数

# 4.用装饰器扩展带有参数的原函数
def kuozhan(func):
def newfunc(who,where):
print("厕所前,萎靡不振")
func(who,where)
print("厕所后,兽性大发") return newfunc @kuozhan
def func(who,where):
print("{}在{}解手".format(who,where)) func("孙致和","鸟窝") # func = newfunc => func("孙致和","鸟窝") <=> newfunc("孙致和","鸟窝")
5.用装饰器扩展带有参数和返回值的原函数

# 5.用装饰器扩展带有参数和返回值的原函数
def kuozhan(func):
def newfunc(*args,**kwargs):
print("厕所前,饥肠辘辘")
res = func(*args,**kwargs)
print("厕所后,酒足饭饱")
return res
return newfunc @kuozhan
def func(*args,**kwargs):
lst = []
dic = {"gaoxuefeng":"高雪峰","sunzhihe":"孙致和","gelong":"戈隆"} # 解手的地点遍历出来
for i in args:
print("拉屎的地点:",i)
for k,v in kwargs.items():
if k in dic:
strvar = dic[k] + "留下了" + v + "黄金"
lst.append(strvar)
return lst lst = func("电影院","水下",gaoxuefeng = "15g",sunzhihe = "15顿",gelong="15斤")
print(lst)
6.用类装饰器扩展原函数

# 6.用类装饰器来拓展原函数
class Kuozhan():
def __call__(self,func):
return self.kuozhan2(func) def kuozhan1(func):
def newfunc():
print("厕所前,老实巴交")
func()
print("厕所后,咋咋乎乎")
return newfunc def kuozhan2(self,func):
def newfunc():
print("厕所前,唯唯诺诺")
func()
print("厕所后,重拳出击")
return newfunc # 方法一
""""""
@Kuozhan.kuozhan1
def func():
print("厕所进行中....") func() # 方法二 @Kuozhan() # @obj => obj(func)
def func():
print("厕所进行中....") func()
7.带有参数的函数装饰器


# 7.带有参数的函数装饰器
def outer(num):
def kuozhan(func):
def newfunc1(self):
print("厕所前,干净整齐")
func(self)
print("厕所后,一片狼藉") def newfunc2(self):
print("厕所前,大腹便便")
func(self)
print("厕所后,满口雌黄") if num == 1:
return newfunc1
elif num == 2:
return newfunc2
elif num == 3:
# 把func3方法变成属性
return "我是女性" return kuozhan class MyClass(): @outer(1) # => (1) kuozhan(func1) => newfunc1 (2) 发动技能做替换 func1 = newfunc1
def func1(self):
print("向前一小步,文明一大步") @outer(2) # => (2) kuozhan(func2) => newfunc2 (2) 发动技能做替换 func2 = newfunc2
def func2(self):
print("来也冲冲,去也冲冲") @outer(3) # => (3) kuozhan(func3) => "我是女性" (2) 发动技能做替换 func3 = "我是女性"
def func3(self):
print("hahaha,lalala") obj = MyClass() obj.func1() # <=> newfunc1
obj.func2()
# obj.func3() error
print(obj.func3)
print(MyClass.func3)
文字解析:
1.套上outer这层函数就是为了保留1 2 3 三个参数,可以在闭包函数中使用
2.调用outer 结束之后,才是返回正常的装饰器kuozhan
3.此刻,@符第一次发动技能,把func1当成参数传递给kuozhan , 返回newfunc1
4.然后,@符第二次发动技能,将返回的newfunc1替换原来func1
if num == 1 返回闭包函数newfunc1
if num == 2 返回闭包函数newfunc2
来做替换
obj.func3 在执行时,装饰器已经把func3变成了属性func3 = "我是女性"
所以obj.func3 或者 MyClass.func3 都是"我是女性" 字符串.
obj.func3 => return "我是女性"
MyClass.func3 => return "我是女性"
8.带有参数的类装饰器
如果参数是1,就为当前类添加成员属性和方法
如果参数是2,就把原方法run变成属性

# 8.带有参数的类装饰器
"""
如果参数是1,就为当前类添加成员属性和方法
如果参数是2,就把原方法run变成属性
"""
class Kuozhan():
money = "贵族厕所,每小时1000元,贵族厕所欢迎您来,欢迎您再来" def __init__(self,num):
self.num = num def __call__(self,cls):
if self.num == 1:
return self.newfunc1(cls) elif self.num == 2:
return self.newfunc2(cls) def ad(self):
print("贵族茅厕,茅厕中的百岁山") def newfunc1(self,cls):
def newfunc():
# 为当前cls这个类,添加属性
cls.money = Kuozhan.money
# 为当前cls这个类,添加方法
cls.ad = Kuozhan.ad
return cls()
return newfunc def newfunc2(self,cls):
def newfunc():
if "run" in cls.__dict__:
# 调用类中的方法,得到对应的返回值
res = cls.run()
# 把返回值重新赋值到run属性上
cls.run = res# cls.run = "亢龙有悔" return cls()
return newfunc
# 参数1
@Kuozhan(1)
class MyClass():
def run():
return "亢龙有悔"
obj = MyClass()
print(obj.money)
obj.ad() # 参数2
@Kuozhan(2)
class MyClass():
def run():
return "亢龙有悔" obj = MyClass()
print(obj.run)
注意点:把类当做参数传递到函数中???
class Ceshi():
ad = 10
obj = Ceshi()
print(obj.ad) # 10 def func(cls):
cls.money = 100
return cls() # 把类当成参数传递到函数当中,在局部空间中,形成独立的副本
obj = func(Ceshi)
# 把类变量Ceshi 变成字符串
Ceshi = "abcde"
# 发现局部空间中类对象中的成员,并没有受到影响
print(obj.money) # 100
面向对象当中的各种方法
普通方法: 有参或者无参,如果是无参,只能类来调用(因为对象调用会自动把obj对象当做参数传进去)
绑定方法: (1) 绑定到对象(自动传递对象参数) 类和对象都可以调用
(2) 绑定到类(自动传递类参数) 类和对象都可以调用,但是推荐使用类来调用 使用装饰器@classmethod
静态方法: 无论是对象还是类,都可以调用此方法,而不会默认传递任何参数 使用装饰器@staticmethod
class Cat():
name = "tom" # 普通方法
def mai_meng():
print("小猫会卖萌") # 绑定方法(对象)
def attack(self):
print("小猫会卅(sua)人") # 绑定方法(类)
@classmethod
def youmi(cls):
print(cls)
print("可以放大招,伤害最高") # 静态方法
@staticmethod
def jump(a,b,c,d,e):
print("小猫会上树,抓老鼠") obj = Cat()
# 普通方法 (无参方法只能类调用)
Cat.mai_meng()
# obj.mai_meng() error # 绑定方法(对象)
obj.attack()
Cat.attack(obj) # 绑定方法(类)
"""对象和类都可以调用绑定到类的方法 推荐使用类来调用"""
Cat.youmi()
obj.youmi()
# print(obj.__class__) # 静态方法
obj.jump()
Cat.jump()
property
property 可以把方法变成属性使用
作用: 控制属性的获取,修改,删除等操作
变向的增加成员的安全性,可以通过自定义的逻辑进行控制
自动触发 : 要求名字相同,同一个名字
获取: @property
设置: @属性名.setter
删除: @属性名.deleter
写法一
# 写法一
class MyClass(): def __init__(self,name):
self.name = name @property
def username(self):
return self.name
# pass # 不获取 @username.setter
def username(self,val):
# 在触发时:val = 朴飘乐 self就是本对象
self.name = val
# pass # 不设置 @username.deleter
def username(self):
# print("删除方法被触发...")
del self.name
# pass # 不删 obj = MyClass("朴一生")
# 获取属性
print(obj.username)
# 设置属性
obj.username = "朴飘乐"
# 获取属性
print(obj.username)
# 删除属性
del obj.username
写法二
# 写法二
class MyClass(): def __init__(self,name):
self.name = name # 获取方法
def get_username(self):
return self.name
# pass # 不获取 # 设置方法
def set_username(self,val):
self.name = val
# pass # 不获取 # 删除方法
def del_username(self):
# del self.name
pass # property(获取方法,设置方法,删除方法)
username = property(get_username,set_username,del_username) # 这三个顺序不可以调换 obj = MyClass("朴仁猛")
# 获取操作
print(obj.username) # 自动触发get_username方法
# 设置操作
obj.username = "pdd" # 自动触发set_username方法
# 删除操作
del obj.username # 自动触发del_username方法
day26:装饰器&面向对象当中的方法&property的更多相关文章
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- Python使用property函数和使用@property装饰器定义属性访问方法的异同点分析
Python使用property函数和使用@property装饰器都能定义属性的get.set及delete的访问方法,他们的相同点主要如下三点: 1.定义这些方法后,代码中对相关属性的访问实际上都会 ...
- day20-Python运维开发基础(装饰器 / 类中的方法 / 类的方法变属性)
1. 装饰器 / 类中的方法 / 类的方法变属性 # ### 装饰器 """ 定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数 优点:在不更改原函数代码的 ...
- [转载]Python使用@property装饰器--getter和setter方法变成属性
原贴:为什么Python不需要getter和setter getter 和 setter在java中被广泛使用.一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和sette ...
- 第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter
上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一. 案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...
- python locust_TaskSet声明任务的典型方法是使用task装饰器的两种方法
为TaskSet声明任务的典型方法是使用task装饰器.该min_wait和MAX_WAIT属性也可以在使用taskset类中重写. from locust import Locust, TaskSe ...
- django class类即视图类添加装饰器的几种方法
根据别人发布整理,个人爱好收集(原文:https://blog.csdn.net/mydistance/article/details/83958655 ) 第一种:定义函数装饰器,在函数,类中使用函 ...
- day11 装饰器---函数的使用方法
这个是一个难点,以后面试会经常出现的,要搞懂! 装饰器升级版,进阶内容1: def outer(flag): def wrapper(func): def inner(*args,**kwargs): ...
- day26:装饰器
装饰器 1.装饰器 : 为原函数去扩展新功能,用新函数去替换旧函数 2.作用 : 在不改变原代码的前提下,实现功能上的扩展 3.符号 : @(语法糖) 1.装饰器的基本用法 # 1.装饰器的基本用法 ...
- 面向对象中的property装饰器讲解
面向对象中可以用property来修饰我们的函数,必须下面的例子 class Test(object): def __init__(self,name): self.name = name @prop ...
随机推荐
- 解决office提示您的许可证不是正版的问题
https://blog.csdn.net/d_pcb66/article/details/125339872?spm=1001.2101.3001.6650.4&utm_medium=dis ...
- MackDown的基础语法与学习(记录代码生活)
MackDown学习 标题 三级标题 四级标题 字体加粗 斜体文字格式 <!--常用的注释--> 删除某行字 插入本地图片 放入一个超链接 https://i.cnblogs.com/po ...
- python for houdini——python在houdini中的基础应用02
内容来源于网上视频 一.houdini python编译器 1.python shell 2.python source editor----代码可以随场景保存 构造的函数可以在外部通过hou.ses ...
- jQuery实现论坛发帖Demo
目录 效果展示 思路 代码 改进空间 效果展示 思路 主要知识点:运用jQuery对HTML元素节点的操作(append)来添加帖子. 交互设计:用户点击页面上的"论坛发帖"按钮, ...
- android系统上编写、运行C#代码
最近找到个好玩的APP,C#Shell (Compiler REPL),可以在安卓系统上编写和运行C#代码,配合sqlite数据库,写了个小爬虫,运行还不错: 运行一些小爬虫或者定时任务可以用这个,毕 ...
- HttpRunner4.x版本调试测试用例时报错 run testcase failed error="abort running due to failfast setting: variable XXX not found" 解决方法
httprunner脚本调试报错 未知变量名称未定义问题 解决了,由于请求的requestBody证件照片链接包含$关键字,需要使用$$转义. 执行脚本报错截图 接口requestBody参数截图 ...
- .NET 6 的 docker 镜像可以有多小
https://blog.csdn.net/sD7O95O/article/details/120135032 Docker Image Size - How to Keep It Small? ht ...
- NuGet国内镜像
NuGet国内镜像 https://nuget.cdn.azure.cn/v3/index.json
- C# 将实体转xml/xml转实体
xml转实体 /// <summary> /// 把xml转换成实体 /// </summary> /// <typeparam name="T"&g ...
- el-scrollbar element-ui的滚动条组件(官方文档没有写出来)
<el-scrollbar></el-scrollbar> //去掉横向滚动条 /deep/.el-scrollbar__wrap { overflow-x: hidden; ...