property,classmethod,staticmethod
1.property(属性方法) :将一个方法伪装成属性。在用时用对象属性的方式调用,只能对象调用
2.classmethod(类方法):将一个普通方法装饰为一个类方法.操作只能和类中的静态变量相关
3.staticmethod(静态方法):将一个方法装饰成普通函数。在类中装饰一个不需要self参数 也不需要cls参数的函数
property
class Circle:
def __init__(self,r):
self.r=r
@property
def area(self):
return self.r**2
@property
def get(self):
return 888
c=Circle(5)
#print(c.area()) #TypeError:此时area是属性
print(c.area) # 25 用属性方法调用。不能用c.area()
classmethod
类方法是被@classmethod装饰的特殊方法:
1.被装饰之后,方法默认接收一个 类 作为参数
2.之后所有的操作都只能和类中的静态变量相关 而不应该和对象相关
3.类和对象都可以直接调用类方法
class Goods:
discount = 0.8
def __init__(self,name,price):
self.name = name
self.price = price
@classmethod
def change_discount(cls,new_dis): # 类方法
cls.discount = new_dis #操作都只能和类中的静态变量相关
#类调用
Goods.change_discount(2)
print(Goods.discount) #2
#对象调用
cig = Goods("jerry",20)
cig.change_discount(0.2)
print(cig.discount) #0.2
staticmethod
class Student:
def __init__(self,name):
self.name = name
@staticmethod #装饰一个不需要self参数 也不需要cls参数的函数
def login(a,b,c): # 普通的函数
return "这是个静态方法"
#类调用
ret = Student.login(1,2,3)
print(ret) #这是个类方法
#对象调用 #这是个类方法
jerd=Student("jerd")
ret = jerd.login(1,2,3)
print(ret)
print(login(1,2,3)) #直接调用会报错,login函数并不在全局中
反射
1.反射的定义
通过字符串来操作python代码中的变量,函数甚至方法和类
hasattr 判断某一个 变量 是否能够.调用一个名字,返回True或者False
getattr 直接获取一个变量中的名字的值
setattr 为一个变量增加或者修改一个属性
delattr 删除一个变量中的属性或者方法
2.hasattr
值=getattr(类名,字符串类型的属性名) 如果第二个参数是不存在的属性名则会报错
hasattr判断属性名是否存在 hasattr常与getattr
class A:
def __init__(self,name,age):
self.name=name
self.age=age
def show(self):
for key in self.__dict__:
print(key,self.__dict__[key])
alex=A("alex",18)
if hasattr(alex,"show"):
func=getattr(alex,"show") #func=self.show得到的是内存地址
func()
3.getattr
class Goods:
discount = 0.8
def __init__(self,name,price):
self.name = name
self.price = price
def post(self):
return "这是post请求"
@property
def get(self):
return "这是属性方法"
@classmethod
def change_discount(cls,new_dis):
cls.discount = new_dis
return "这是类方法"
@staticmethod
def login(a, b, c):
return "这是个静态方法"
1.反射类中的名字
getattr(类名,'类属性')
getattr(类名,'类方法名')()
getattr(类名,'静态方法名')()
getattr(类名,'对象方法名')(self)
#1.反射类属性
ret=getattr(Goods,"discount")
print(ret) #0.8
#2.反射类方法
ret=getattr(Goods,"change_discount")
print(ret(10)) #这是类方法
#3.反射静态方法
ret=getattr(Goods,"login")
print(ret(1,2,3)) #这是个静态方法
ret=getattr(Goods,"post")
#4.反射对象方法,参数为类名或者类的对象
print(ret(Goods)) #这是post请求
obj=Goods("jerd",20)
print(ret(obj)) #这是post请求
2.反射对象中的名字
getattr(对象名,'类属性')
getattr(对象名,'对象属性')
getattr(对象名,'对象方法名')()
getattr(对象名,'属性方法名')
getattr(对象名,'类方法名')()
getattr(对象名,'静态方法名')()
obj=Goods("jerd",20)
#1.反射类属性
ret=getattr(obj,"discount") #ret=obj.discount
print(ret) # 0.8
#2.反射对象属性
ret=getattr(obj,"name") #ret=obj.name
print(ret) #jerd
#3.反射对象方法
ret=getattr(obj,"post") #ret=obj.post
print(ret()) #这是post请求
#4.反射属性方法
ret=getattr(obj,"get") #ret=obj.get
print(ret) #这是属性方法
#5.反射类方法
ret=getattr(obj,"change_discount") #ret=obj.change_discount
print(ret(2)) #这是类方法
#6.反射静态方法
ret=getattr(obj,"login") #ret=obj.login
print(ret(1,2,3)) #这是个静态方法
3.反射类
import sys
main=sys.modules[__name__]
class A:pass
cls=getattr(main,'A')
import sys
count=0
sum=100
class A():
def get(self):
print("这是practice文件")
main=getattr(sys.modules[__name__],"A")
print(main) #<class '__main__'.A'>
main().get() #这是practice文件
4.反射当前模块中的名字
import sys
getattr(sys.modules[__name__],'变量')
getattr(sys.modules[__name__],'函数')()
getattr(sys.modules[__name__],'类名')
import sys
count=0
sum=100
def post():
return "这是post请求"
class A():
def get(self):
print("这是practice文件")
#1.反射当前类中变量
main=getattr(sys.modules[__name__],"sum")
print(main) #100
#2.反射当前模块中的函数名
main=getattr(sys.modules[__name__],"post")
print(main()) #这是post请求
#3.反射当前模块中得类名
main=getattr(sys.modules[__name__],"A")
main().get() #这是practice文件
#4.下面会报错,get在类A内存中,不在当前模块的内存中,因此找不到
main=getattr(sys.modules[__name__],"get")
main(A)
5.模块中反射
import 模块名
getattr(模块名,'模块中的变量')
getattr(模块名,'模块中的函数')()
getattr(模块名,'模块中的类名')
practice.py
import sys
count=0
sum=100
def post():
return "这是post请求"
class A():
def get(self):
print("这是practice文件")
practice1.py
count=1
import practice
import sys
class A():
def get(self):
print("这是practice1文件")
#1.反射practice模块中的变量
print(getattr(practice,"sum")) #100
#2.反射practice模块中的函数名
ret=getattr(practice,"post")
print(ret()) #这是post请求
#3.反射practice模块中的类名
ret=getattr(practice,"A")
print(ret) #<class 'practice.A'>
4.setattr
class A():
def __init__(self,name):
self.name=name
def get(self):
print("get is ",self.name)
def post(self):
print("这是post请求")
def __getattr__(self,item):
print(666)
return item
a=A("jerd")
1.反射类中方法:
getattr(a,"get")() #get is jerd
getattr(a,"post")() #这是post请求
2.重新赋值:
#对静态属性更改
print(a.name) #jerd
setattr(a,"name","zhaoguangfei") #此操作的结果a.name=zhaoguangfei
print(a.name) #zhaoguangfei
#对函数名更改
setattr(a,"get",a.post) #将a.get修改为a.post
handler=getattr(a,"get") 正常的handler值为a.get但是使用setattr设置后a.get的值就是a.post
print(handler()) #这是post请求
#增加
setattr(a,"sex","man") #为对象a添加sex属性,a.sex=man
print(a.sex) #man
5.__getattr__
调用的属性不存在时,会执行getattr
print(a.sb) #666 sb
print(getattr(a,"sb")) #666 sb
如果getattr不存在,再调用a.sb时报错
6.delattr
class A:
def __init__(self,name):
self.name=name
alex=A("alex")
print(alex.name) #alex
delattr(alex,'name')
print(alex.name) #AttributeError: 'A' object has no attribute 'name'
'__main__'和__name__
practice.py
import sys
count=0
sum=100
def post():
return "这是post请求"
class A():
def get(self):
print("这是practice文件")
print(sys.modules["__main__"])
practice1.py
count=1
import practice
import sys
class A():
def get(self):
print("这是practice1文件")
使用sys.modules["__main__"]时,如果在另一个文件中导入了当前文件,执行另一个文件会显示另一个文件名的名字
使用sys.modules[__name__]时, 在另一个文件中也会显示当前文件的名字
执行practice.py #<module '__main__' from 'E:/lianxi/practice.py'>
执行practice1.py #<module '__main__' from 'E:/lianxi/practice1.py'> 显示当前文件名
将practice.py中print(sys.modules["__main__"])换成print(sys.modules[__name__])
practice.py
import sys
count=0
sum=100
def post():
return "这是post请求"
class A():
def get(self):
print("这是practice文件")
print(sys.modules[__name__])
执行practice.py #<module '__main__' from 'E:/lianxi/practice.py'>
执行practice1.py #<module 'practice' from 'E:\\lianxi\\practice.py'> #显示导入的文件名
在practice.py中添加:
执行practice.py:
print(getattr(sys.modules['__main__'],"count")) #0
print(getattr(sys.modules[__name__],"count")) #0
执行practice1.py:1,0
import sys
print(sys.modules) #所有导入过的模块 {'builtins': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>.....}
for i in sys.modules:
print(i,sys.modules[i]) #_main__ <module '__main__' from 'D:/lianxi/lizi.py'>
print(sys.modules[__name__])
'__main__': <module '__main__' from 'D:/lianxi/lizi.py'> 模块名后面是内存地址
{'字符串数据类型的模块名':模块的内存地址}
{'__main__':当前模块的内存地址}