1.反射

# ### 反射(针对于类对象 模块)
'''概念:通过字符串去操作类对象或者模块当中的成员(属性方法)''' class Man():
pass class Woman():
pass class Children(Man,Woman):
'''
成员属性:eye
成员方法:skylight moonread __makebaby
完成的功能:描述小孩天生神力
'''
eye = "血轮眼" def skylight(self):
print("一下生,直接使用天照,让世界变得混乱") def moonread(self,func):
print("一下生,使出了武功绝学,月度,世界都黑暗了")
print(func.__name__,type(func.__name__)) def __makebaby(self):
print("这一手招数,只能我自己用")
obj = Children() #(1) 反射类对象中的成员
# hasattr() 检测对象/类是否有指定的成员
#对象
res = hasattr(obj,"eye")
print(res) #True #类
res = hasattr(Children,"skylight") #True
res = hasattr(Children,"__makebaby") #False
print(res) # getattr() 获取对象/类成员的值
#对象
func = getattr(obj,"skylight")
func = getattr(obj,"__makebaby") #报错
func() # =>skylight() 通过对象反射出来的方法是绑定方法 #类
func = getattr(Children,"skylight")
func(1) #通过类反射出来的是一个普通方法 #当类对象中的成员不存在时,可以设置默认值(第三个参数是默认参数)
func = getattr(obj,"moonread123","对不起,该成员不存在")
print(func) #综合案例
'''
strvar = input("请输入你要调用的方法")
if hasattr(obj,strvar): #判断obj对象是否有这个属性
func = getattr(obj,strvar) #获取对象的这个属性
func()
''' #setattr() 设置对象/类成员的值
#对象
setattr(obj,"eye","白眼")
print(obj.eye)
#类
setattr(Children,"tcut",lambda : print("小孩一下生就能使用雷切"))
Children.tcut()
#obj.tcut() #tcut是一个无参普通方法,只能类调用 #delattr() 删除对象/类成员的值 #对象
delattr(obj,"eye")
print(obj.eye) #类
delattr(Children,'eye')
print(Children.eye) #(2)反射模块中的成员
'''sys.modules返回一个系统的字典,加载系统模块展现出来'''
import sys
print(sys.modules) #获取本模块的对象
print(sys.modules["__main__"])
selfmodule = sys.modules["__main__"] def func1():
print("我是func1方法") def func2():
print("我是func2方法") def func3():
print("我是func3方法") #综合案例
while True:
strvar = input("请输入你要反射的方法")
if hasattr(selfmodule,strvar)
func = getattr(selfmodule,strvar)
func()
elif strvar.upper() == "Q":
break
else:
print("没有这个方法")

2.装饰器

# ### 装饰器
'''
装饰器:为原函数扩展新功能,用新功能去替代旧功能
作用:在不改变原有代码的基础上,实现功能上的扩展
符号:@(语法糖)
''' # 1.装饰器的基本使用
def outer(f):# f = func
def inner():
print("测试前")
f()
print("测试后")
return inner
def func():
print("我叫高富帅") func = outer(func)
func() #func() = inner() #2. @符号的使用
'''
@符号使用:
(1)可以自动把@符号下面的函数当成参数传递给装饰器
(2)把新函数进行返回,让新函数去替换旧函数,以实现功能的扩展
# func = inner <==> func() = inner()
'''
def outer(f): #f = func
def inner():
print("测试前")
f() #真正执行函数的调用 =func
print("测试后")
return inner
@outer #先调用outer,并把下面函数名传给参数f,即func = outer(func)
def func(): #被调用的真正函数
print("我叫高富帅") func() #func() = inner() #3.装饰器的嵌套
def outer1(f):
def inner():
print("测试前1")
f()
print("测试后2")
return inner def outer2(f):
def inner():
print("测试前3")
f()
print("测试后4")
return inner
@outer2 #3 1 5 2 4
@outer1 #调用outer1并把func传给f 1 5 2
def func():
print("我是白富美5")
func() #31524
'''
解析
1.调用outer1并把func传给f,返回inner,执行func()想当于执行inner()
outer1的打印顺序为 1 5 2
2.然后再调用outer2把func传给f,返回inner,执行func()想当于执行inner()
outer2的打印顺序为3 1 5 2 4
''' #4.用装饰器修饰带有参数的函数
'''拓展的新功能和原函数的功能,在参数和返回值上,要保持一致性'''
def outer(f):
def inner(who,where):
print("测试前")
f(who,where)
print("测试后")
return inner
@outer # func = outer(func)
def func(who,where):
print("{who}在{where}吃饭".format(who=who,where=where)) func("小白","餐厅") #5.用装饰器修饰带有参数返回值的函数
def outer(f):
def inner(*args,**kwargs): # 函数的定义处, *号的打包操作
print("测试前")
res = f(*args,**kwargs) # 函数的调用处,*号解包操作
print("测试后")
return res
return inner @outer #func = outer(func)
def func(*args,**kwargs):
dic = {"wz":"王振","xb":"小白","ww":"伟伟"}
lst = []
strvar = "" #遍历玩耍的地点
for i in args:
print("玩耍的地点",i)
#print(args)
#print(kwargs)
'''
正常写法
for k,v in kwargs.items():
if k in dic:
strvar = dic[k] + "留下" + v + "黄金"
lst.append(strvar)
return lst
'''
#推导式
return [dic[k] + "留下" + v + "黄金" for k,v in kwargs.items() if k in dic]
#谁留下多少黄金
res = func("电影院",'水里',wz="18斤",xb="18吨",ww="18克",zzz = "19k")
print(res) #6. 用装饰器来拓展原函数
class outer():
def __call__(self,func): #第二步 #触发call方法,把func传给func
return self.outer1(func) #第三步 #调用outer1并把func传给func def outer1(self,func): #第四步
def inner(): #第七步 #执行第六步相当于执行这一步func()=inner()
print("测试前1") #第八步 打印
func() #第九步 #真正函数调用打印测试进行时
print("测试后2") #第十二步
return inner #第五步 #func = inner def outer2(func):
def inner():
print("测试前3")
func() #真正函数调用打印测试进行时
print("测试后4")
return inner
#方法一
'''
@outer.outer2 outer(func).outer2
def func():
print("测试进行时...")
func()
''' #方法二
'''
@outer() => @obj<=>对象 => obj(func) <=>把对象当成函数进行使用了,自动触发__call__魔术方法
把新函数inner返回了 => @发动第二个既能,将新函数去替换旧函数,func = inner
func() = inner() def func():
print("测试进行时...")
func()
'''
@outer() #第一步 #outer() = > obj对象,然后@obj => func = obj(func),把obj对象当做函数调用会自动触发call方法
def func(): #第十步 执行第九步 就相当于执行真正的函数调用
print("测试进行时") #第十一步
func() #第六步 func() = inner() #7. 带有参数的函数装饰器
def outer(num):
def kuozhan(func): #第二步 #func = func1
def inner1(self): #第五步 调用func1相当于调inner1
print("测试前1")#第六步
res = func(self) #第七步
print("测试后2") #第十步
return res def inner2(self):
print("测试前3")
res = func(self)
print("测试后4")
return res if num == 1:
return inner1 #第三步 #func1 = inner1
elif num == 2:
return inner2
elif num == 3:
#把方法变成属性
return "我是男性"
return kuozhan class MyClass():
@outer(1)#第一步 outer(1)=>返回kuozhan,@kuozhan=> func1=kuozhan(func1)[@符号第一次发动技能] <=> func2 = newfunc2 [@符号第二次发动技能]
def func1(self): #第八步,第七步执行的真正函数是这个
print("试一试") #第九步 @outer(2)#outer(2)=>返回kuozhan ,@kuozhan <==> func2=kuozhan(func2) [@符号第一次发动技能] <=> func2 = newfunc2 [@符号第二次发动技能]
def func2(self):
print("拼一拼") @outer(3)
def func3():# outer(3)=>kuozhan , @kuozhan <=> func3=kuozhan(func3) [@符号第一次发动技能] <=> func3 = "我是男性"
print("搏一搏")
obj = MyClass()
obj.func1() #第四步
obj.func2() #func2() <==> newfunc2()
#把方法变成属性
print(obj.func3) #func3=kuozhan(func3) => func3 = "我是男性" #8.带有参数的类装饰器
'''
如果参数是1,就为当前类添加成员属性和方法
如果参数是2,就把原方法run变成属性
'''
class outer():
ad = "贵族茅房,每小时100元,贵族茅房,欢迎您来,欢迎您再来"
def __init__(self,num):
self.num = num def __call__(self,cls): #第二步 把MyClass传入 cls接收
if self.num == 1:
return self.inner1(cls) #第三步 执行inner1函数
elif self.num == 2:
return self.inner2(cls) def money(self):
print("茅中贵族,百岁山") #参数为1的情况
def inner1(self,cls): #第四步 cls接收MyClass
def inner(): #第七步
#为当前cls这个类,添加属性(为MyClass)
cls.ad = outer.ad #第八步
#为当前cls这个类,添加方法(为MyClass)
cls.money = outer.money #第九步
return cls() #第十步 #对象obj = cls()
return inner # 第五步 返回 MyClass = inner #参数为2的情况
def inner2(self,cls):
def inner():
if "run" in cls.__dict__:
#调用类中的方法,拿到返回值
res = cls.run()
#把返回值重新赋值给run属性,后者覆盖了前者,方法变成了属性
cls.run = res #再把值赋值给MyClass的run属性
return cls() #返回对象 return inner
#obj = outer(1)
'''
@obj [@符号第一次发动技能] <==>obj(MyClass) 把对象当成函数使用了,触发__call__魔术方法
self.inner1(cls) <==> return inner
<==> [@符号第二次发动技能] 将新函数替换旧函数 MyClass = inner
obj = MyClass() <==> inner() => cls() => obj对象 情况一
@outer(1) #第一步 @obj => MyClass = obj(MyClass) 对象obj当成函数调用触发call方法
class MyClass():
def run():
return "亢龙有悔"
obj = MyClass() #第六步 MyClass() = inner() = cls()
print(obj.ad) #第十一步
obj.money()
''' '''
@obj [@符号第一次发动技能] <==> obj(MyClass) 把对象当成函数使用了,触发__call__魔术方法
self.inner2(cls) <==> return inner
<==> [@符号第二次发动技能] 将新函数替换旧函数 MyClass = inner
obj = MyClass() <==> inner() => cls() => obj对象
'''
#情况二
@outer(2) # outer(2) => obj对象,@obj => MyClass = obj(MyClass),obj(MyClass) 把对象当成函数使用了,触发__call__魔术方法
class MyClass():
def run():
return "亢龙有悔"
obj = MyClass() # MyClass() => inner()返回cls() => obj
print(obj.run) #亢龙有悔 '''
obj = MyClass()的解释
#第一部分 定义一个类
class Ceshi():
c = 100
obj = Ceshi()
print(obj.c) #第二部分,定义两个函数
def func22():
print(111) def func(cls):
cls.aabbcc = 200
obj = cls()
return obj #第三部分,把类当成参数传递给func,类在func函数中形成了一个独立的副本
obj= func(Ceshi) #第四部分,把这个类做替换,变成函数,那么现在在全局空间的Ceshi已经变成了函数,不再是类
Ceshi = func22 #第五部分,调用局部空间obj,还是可以得到原来类中的成员属性和方法
print(obj.c)
print(obj.aabbcc)
'''

3.类当中的方法

# ### 面向对象中的方法
'''
普通方法:可以有参数,或者无参数,当成正常的函数调用
绑定方法:(1)绑定到对象(自动传递参数为对象)(2)绑定到类(自动传递参数为类)
静态方法:无论是对象还是类,都可以调用,默认不用传递任何参数
''' class Dog():
name = "旺财" #普通方法
def jiao():
print("小狗哇哇哇的叫唤") #绑定方法(对象)
def eat(self):
print("小狗喜欢吃骨头") #绑定方法(类) 类方法
@classmethod
def tail(cls):
print(cls)
print("小狗看到主人喜欢摇尾巴") #静态方法
@staticmethod
def jump(num):
print("小狗喜欢接飞盘")
obj = Dog()
#普通方法(无参方法只能类调用)
#obj.jiao() error
Dog.jiao() #绑定self方法(一般用对象调用)
obj.eat() #推荐
Dog.eat(123) #类调用绑定方法 不推荐 #绑定类方法(classmethod类的专属方法推荐用类调用)
'''系统自己把类当成参数进行传递'''
Dog.tail() #类调用方法 推荐
obj.tail() #静态方法(staticmethod不会默认传递任何参数,如果有参数,当成普通方法调用自己)
obj.jump(1)
Dog.jump(2) ### 在类外,为对象添加成员方法,默认皆是静态方法
obj.func = lambda : print(123)
obj.func()

4.property装饰器

# ### 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):
print(2131231)
val = "朴仁猛"
self.name = val @username.deleter
def username(self):
#如果发现有删除行为,可以在这个方法中拒绝删除
#pass
del self.name
obj = MyClass("小芳") #获取属性(自动触发获取方法@property)
#print(obj.username())#TypeError: 'str' object is not callable
print(obj.username) #把方法当做属性 #设置属性(自动触发设置方法)val形参自动接收设置的值
obj.username = "朴仁猛"
print(obj.username) #删除属性
del obj.username
#print(obj.username) error #方法二
class MyClass():
def __init__(self,name):
self.name = name #获取
def get_username(self):
return self.name #设置
def set_username(self,val):
# val = "朴仁猛"
self.name = val #删除
def del_username(self):
#如果发现有删除行为,可以在这个方法中拒绝删除
del self.name #顺序必须按照 获取 ->设置 ->删除的参数进行传递
username = property(get_username,set_username,del_username) obj = MyClass("朴飘乐")
#获取
print(obj.username)
#设置
obj.username = "朴一辈"
print(obj.username)
#删除
del obj.username
print(obj.username) #error 被删掉了

总结:

今天主要讲了反射 装饰器,类当中的方法普通方法,类方法,静态方法,property装饰
反射就是通过字符串去操作对象或者模块中的成员(属性或者方法)
可以反射类或者对象中的成员
主要有
hasattr 检测类或者对象中是否有该成员 返回True或者False
getattr 获取类或者对象中的成员 存在则获取到,不存在则报错,可以设置第三个参数防止报错
setattr 设置类或者对象成员的值
delattr 删除类或者对象成员 装饰器函数
为原函数拓展新功能,用新功能去替代旧功能
作用:在不改变原有代码的基础上,实现功能上的拓展
符号:@符号
@符号的作用
自动把@符号下面的函数当成参数传递给装饰器
把新函数进行返回,让新函数去替换旧函数,以实现功能的拓展 装饰器的嵌套
用装饰器修饰带有参数的函数
用装饰器修饰带有参数返回值的函数
装饰器拓展原函数
带有参数的函数装饰器
带有参数的类装饰器 面向对象中的方法
普通方法:可以有参数,或者无参数,当成正常的函数调用
绑定方法:绑定到对象(自动传递参数为对象)self方法(2)绑定到类(自动传递参数为类)类方法,需要用@classmethod装饰,参数至少为一个cls
静态方法:@staticmethod 无论对象还是类,都可以调用,默认不用传递任何参数 property装饰器
可以把方法变成属性使用
作用控制属性的获取 设置 删除操作
变相的增加成员的安全性,可以通过自定义逻辑对成员进行控制 自动触发的时候,要求是用一个名字
获取 @property
设置 @属性名.setter
删除 @属性名.deleter

反射,装饰器,类当中的方法,property---day24的更多相关文章

  1. day26:装饰器&面向对象当中的方法&property

    目录 1.装饰器 1.1 装饰器的基本用法 1.2 @符号的使用 1.3 装饰器的嵌套 1.4 用装饰器扩展带有参数的原函数 1.5 用装饰器扩展带有参数和返回值的原函数 1.6 用类装饰器扩展原函数 ...

  2. day20-Python运维开发基础(装饰器 / 类中的方法 / 类的方法变属性)

    1. 装饰器 / 类中的方法 / 类的方法变属性 # ### 装饰器 """ 定义:装饰器用于拓展原来函数功能的一种语法,返回新函数替换旧函数 优点:在不更改原函数代码的 ...

  3. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  4. Python使用property函数和使用@property装饰器定义属性访问方法的异同点分析

    Python使用property函数和使用@property装饰器都能定义属性的get.set及delete的访问方法,他们的相同点主要如下三点: 1.定义这些方法后,代码中对相关属性的访问实际上都会 ...

  5. [转载]Python使用@property装饰器--getter和setter方法变成属性

    原贴:为什么Python不需要getter和setter getter 和 setter在java中被广泛使用.一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和sette ...

  6. 第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter

    上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一.    案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...

  7. django class类即视图类添加装饰器的几种方法

    根据别人发布整理,个人爱好收集(原文:https://blog.csdn.net/mydistance/article/details/83958655 ) 第一种:定义函数装饰器,在函数,类中使用函 ...

  8. java反射 顺序输出类中的方法

    java反射可以获取一个类中的所有方法,但是这些方法的输出顺序,并非代码的编写顺序. 我们可以通过自定义一个注解来实现顺序输出类中的方法. 首先,先写一个类,定义增删改查4个方法 public cla ...

  9. python_如何定义装饰器类?

    案例: 实现一个能将函数调用信息记录到日志的装饰器 需求: 把每次函数的调用时间,执行时间,调用次数写入日志 可以对被装饰函数分组,调用信息记录到不同日志 动态修改参数,比如日志格式 动态打开关闭日志 ...

  10. python locust_TaskSet声明任务的典型方法是使用task装饰器的两种方法

    为TaskSet声明任务的典型方法是使用task装饰器.该min_wait和MAX_WAIT属性也可以在使用taskset类中重写. from locust import Locust, TaskSe ...

随机推荐

  1. [转帖]kill 参数表

    https://www.cnblogs.com/alix-1988/p/14331898.html kill命令格式:kill -Signal pidpid是进程号,可以用 ps 命令查出 signa ...

  2. [转帖]VLAN与三层交换机

    目录 一.VLAN概述与优势 二.Trunk的作用 三.IEEE 802.1q 四.VLAN转发 五.Trunk的配置 六.单臂路由概述 七.三层交换机实现VLAN之间通信的原理 八.实验一 九.实验 ...

  3. Linux 下面删除指定日期之前文件的办法

    1. Linux 下面最近有一个需求 需要只更新2020年4月10号之后补丁的需求 2. rsync 能够拉取所有的补丁文件  没找到能够按照日期进行拉取的办法. 所以想了一个折中的办法 先拉取 再按 ...

  4. Redis6.x 在Windows上面编译安装的过程

    背景说明 在github上面仅能够找到 redis3.2.100的Windows安装文件 比较新的版本比较难以找到, 同事经常出现这个版本的redis卡死的情况, 所以想尝试进行一下升级. 第一部分下 ...

  5. 前端 Git-Hooks 工程化实践

    前言 前段时间,部门的前端项目迁移到 monorepo 架构,笔者在其中负责跟 git 工作流相关的事情,其中就包括 git hooks 相关的工程化的实践.用到了一些常用的相关工具如 husky.l ...

  6. js中for in和for of详细讲解

    for in的详细讲解, for in遍历数组的毛病 1.index索引为字符串型数字,不能直接进行几何运算. 2.遍历顺序有可能不是按照实际数组的内部顺序 3.使用for in会遍历数组[所有的可枚 ...

  7. uni-app三目运算 uni-app监听属性

    三目运算 <text>{{mag>10 ? '优秀' : ""}}</text> 三目运算的高级用法 大于1000用kg表示 小于1000,用g表示 ...

  8. VictoriaMetrics 1.73.1 值得关注的新特性

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu 公众号:一本正经的瞎扯 VictoriaMetrics 1.73.1 的changelog: h ...

  9. C语言输出键盘

    使用printf()函数输出样式 #include <stdio.h> int main() { printf("┌───┬───┬───┬───┬───┬───┬───┬─── ...

  10. Flask WTForms 表单插件的使用

    在Web应用中,表单处理是一个基本而常见的任务.Python的WTForms库通过提供表单的结构.验证和渲染等功能,简化了表单的处理流程.与此同时,Flask的扩展Flask-WTF更进一步地整合了W ...