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. [转帖]如何提高Linux下块设备IO的整体性能?

    http://www.yunweipai.com/6989.html 运维派隶属马哥教育旗下专业运维社区,是国内成立最早的IT运维技术社区,欢迎关注公众号:yunweipai领取学习更多免费Linux ...

  2. MYSQL 简单验证

    建立测试表 create table test001 (a varchar(2000),b varchar(2000),c varchar(2000),d varchar(2000),e varcha ...

  3. Jumper Server 堡垒机搭建过程

    Jumper Server 堡垒机搭建过程 背景说明 公司组织考核, 要对一套系统进行安全设置.有一个项目是使用堡垒机进行登录 堡垒机有多种用途,可以实现日志审计和安全设置等. 买商业设备的话太困难了 ...

  4. bean的一生

    你曾读spring源码 "不知所云"."绞尽脑汁"."不知所措"嘛 那这篇文章可能会对你有所帮助,小编尝试用简单.易懂的例子来模拟sprin ...

  5. (数据科学学习手札113)Python+Dash快速web应用开发——表单控件篇(下)

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 由我开源的先进Dash组件库feffery-antd-co ...

  6. Go泛型简介

    Go语言的泛型是在Go 1.18版本中引入的一个新特性,它允许开发者编写可以处理不同数据类型的代码,而无需为每种数据类型都编写重复的代码.以下是关于Go语言泛型的一些关键点: 泛型是通过在函数或类型定 ...

  7. 微信小程序-页面跳转Tabbar

    官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar 首先我们 ...

  8. 【六】强化学习之DQN---PaddlePaddlle【PARL】框架{飞桨}

    相关文章: [一]飞桨paddle[GPU.CPU]安装以及环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简 ...

  9. 6.5 Windows驱动开发:内核枚举PspCidTable句柄表

    在 Windows 操作系统内核中,PspCidTable 通常是与进程(Process)管理相关的数据结构之一.它与进程的标识和管理有关,每个进程都有一个唯一的标识符,称为进程 ID(PID).与之 ...

  10. nginx入门之安装和启动

    1.安装环境 nginx 使用源码编译安装,环境及组件如下: make 环境 openssl-fips-2.0.10 pcre-8.44 zlib-1.2.11 nginx-1.10.2 需要注意各组 ...