zoukankan      html  css  js  c++  java
  • 《Python》 property、classmethod、staticmethod、isinstance、issubclass

    一、property

        property是一个装饰器函数

          装饰器函数的使用方法:在函数、方法、类的上面一行直接@装饰器的名字

        装饰器的分类:

          1、装饰函数

          2、装饰方法:property

          3、装饰类

    import math
    class Circle:
        def __init__(self,radius): #圆的半径radius
            self.radius=radius
    
        @property
        def area(self):
            return math.pi * self.radius**2 #计算面积
    
        @property
        def perimeter(self):
            return 2*math.pi*self.radius #计算周长
    
    c=Circle(10)
    print(c.radius)
    print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
    print(c.perimeter) #同上
    '''
    输出结果:
    314.1592653589793
    62.83185307179586
    '''

      为什么要用property

        将一个类的函数定义成特性以后,对象再去使用的时候c.area,根本无法察觉自己的area是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

      

    class Student:
        def __init__(self,name):
            self.__name = name
    
        @property   # 把方法伪装成属性
        def name(self):
            return self.__name
    
        @name.setter    # 用setter装饰一个跟property同名的方法
        def name(self,new):
            if type(new) is str:
                self.__name = new
    
    obj = Student('小明')
    print(obj.name)     # 小明
    obj.name = '小红'   # 赋值的时候,就触发被setter装饰器装饰的方法
    print(obj.name)     # 小红
    
    # 好处:用来保护一个变量,在修改的时候能够添加一些保护条件
    class Goods:
        __discount = 0.8    # 全场8折
        def __init__(self,price):
            self.__price = price    # 商品原价
    
        @property
        def price(self):
            return Goods.__discount * self.__price  # 折后价
    
        @price.setter
        def price(self,new):
            self.__price = new  # 更改原价
    
        @price.deleter
        def price(self):
            del self.__price    # 删除商品价格
    
    apple = Goods(10)
    print(apple.price)  # 8.0
    apple.price = 8   # 重新赋值
    print(apple.price)  # 6.4
    del apple.price     # 删除属性
    
    # 一个方法被伪装成属性后
    # 应该可以执行一个属性的增删改查操作
    # 那么增加和修改,就对应这setter装饰的方法:这个方法有一个必传的参数new,表示赋值的时候等号后面的值
    # 删除一个属性,对应着被deleter装饰的方法,这个方法并不能在执行的时候真的删除这个属性,而是你在代码中执行什么就有什么效果
    
    class A:
        def __init__(self):
            self.__f = open('aaa','w')
            
        @property
        def f(self):
            return self.__f
        
        @f.deleter
        def f(self):
            self.__f.close()    # 删除一个文件,要先关闭文件
            del self.__f

    二、classmethod

        在类中定义一个类方法、是一个装饰器

        什么时候用

          如果你的整个方法中都没有用到对象命名空间中的名字,且你用到了类的命名空间中的名字(普通方法和property方法除外)

        类方法的默认参数:cls指的是调用这个方法的类

        类方法的调用方式:通过类名调用,本质是方法
        类方法的特点:
          只使用类中的资源,且这个资源可以直接用类名引用的使用,那这个方法应该被改成一个类方法
            静态属性
            普通方法
            类方法
            property方法

    class Goods:
        __discount = 0.8    # 静态属性(全场8折)
        def __init__(self,price):
            self.__price = price    # 对象属性
            self.name = 'apple'
    
        @property
        def price(self):
            print(self)
            return self.__price * Goods.__discount  # 折后价
    
        @classmethod
        def change_discount(cls,new):   # 类方法
            cls.__discount = new
    
    # Goods.change_discount(0.7)  # 把折扣价改成7折
    # print(Goods.__dict__)
    '''
    {'__module__': '__main__', '_Goods__discount': 0.7, '__init__': <function Goods.__init__ at 0x01688DB0>,
        'price': <property object at 0x01693A50>, 'change_discount': <classmethod object at 0x0160E0F0>,
        '__dict__': <attribute '__dict__' of 'Goods' objects>,
        '__weakref__': <attribute '__weakref__' of 'Goods' objects>, '__doc__': None}
    '''
    
    apple = Goods(10)
    banana = Goods(20)
    apple.change_discount(0.7)  # 把折扣价改成7折
    print(apple.price)  # 7
    print(banana.price) # 14
    # 类:
    #   静态属性  类  所有的对象都统一拥有的属性                        
    #   类方法   类  如果这个方法涉及到操作静态属性、类方法、静态方法              cls 表示类
    #   静态方法  类  普通方法,不使用类中的命名空间也不使用对象的命名空间 : 一个普通的函数   没有默认参数
    #   方法    对象                                       self 表示对象
    #   property  对象                                       self 表示对象

    三、staticmethod
       
    将一个普通的函数放到类中来就给这个函数加上一个@staticmethod装饰器
       这个函数就不需要传默认的参数:self,cls
       静态方法的调用方式:通过类名调用,本质还是函数


    class Staticmethod_Demo():
        role = 'dog'
    
        @staticmethod
        def func():
            print("当普通方法用")
    
    Staticmethod_Demo.func()
    class Foo:
        @classmethod
        def class_method(cls):pass
    
        @staticmethod
        def static_method():pass
    
    from types import MethodType,FunctionType
    obj = Foo()
    print(isinstance(Foo.class_method,MethodType))      # True  判断它是否一个方法
    print(isinstance(Foo.static_method,FunctionType))   # True  判断它是否一个函数
    print(obj.class_method)     # <bound method Foo.class_method of <class '__main__.Foo'>>
    print(obj.static_method)    # <function Foo.static_method at 0x013A8DB0>



    四、isinstance
        检测对象与类之间的关系
    print(type(123) is int)     # True
    print(isinstance(123,int))  # True
    
    class A:
        pass
    class B(A):
        pass
    a = A()
    b = B()
    print(type(a) is A) # True
    print(type(a) is B) # False
    print(type(b) is A) # False
    print(type(b) is B) # True
    
    print(isinstance(a,A))  # True
    print(isinstance(b,A))  # True
    print(isinstance(a,B))  # False
    print(isinstance(b,B))  # True
    
    # isinstance就是检测对象与类之间的关系
    五、issubclass
        检测类与类之间的关系
    class A:
        pass
    class B(A):
        pass
    print(issubclass(A,B))  # False
    print(issubclass(B,A))  # True
    
    # issubclass就是检测类与类之间的关系





  • 相关阅读:
    最短路之dijkstra算法
    拓扑排序 topsort详解
    POJ2236 Wireless Network 并查集简单应用
    最小生成树详解 prim+ kruskal代码模板
    并查集详解及模板
    POJ 3190 Stall Reservations贪心
    chapter22:源码与Tarball之(1)-传统方法编译与make方法进行编译
    vi的用法
    centos7 connect internet
    java内存区域
  • 原文地址:https://www.cnblogs.com/yzh2857/p/9563017.html
Copyright © 2011-2022 走看看