property classmethod staticmethod和反射

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__':当前模块的内存地址}
posted @ 2018-06-21 16:32  JERD  阅读(215)  评论(0编辑  收藏  举报