zoukankan      html  css  js  c++  java
  • 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__':当前模块的内存地址}
  • 相关阅读:
    hdu4612 无向图中随意加入一条边后使桥的数量最少 / 无向图缩点+求树的直径
    Python 之 安装模块的多种方法
    开源项目Universal Image Loader for Android 说明文档 (1) 简单介绍
    IDEA下使用Jetty进行Debug模式调试
    离线安装Cloudera Manager5.3.4与CDH5.3.4(一)
    让你提前认识软件开发(38):完毕第一个新需求
    Windows App开发之经常使用控件与应用栏
    【剑指Offer学习】【面试题58:二叉树的下一个结点】
    【Win】编写简单的bat文件
    【Linux】MySQL解压版安装及允许远程访问
  • 原文地址:https://www.cnblogs.com/zgf-666/p/9209739.html
Copyright © 2011-2022 走看看