python--面向对象高级用法

前提是你 提交于 2019-12-18 02:09:32

1. @装饰器

用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。

有多个装饰器执行的顺序是从最后一个装饰器开始,执行到第一个,再执行函数本身

def dec1(func):  
    print("1111")  
    def one():  
        print("2222")  
        func()  
        print("3333")  
    return one  
  
def dec2(func):  
    print("aaaa")  
    def two():  
        print("bbbb")  
        func()  
        print("cccc")  
    return two  
 
@dec1  
@dec2  
def test():  
    print("test test")  
  
test()  

结果:

 

2. @property 与getter setter  

 

描述符

描述符就是一个“绑定行为的对象属性”,在描述符协议中,它可以通过方法充写属性的访问。这些方法有get(),set(),delete().如果这些方法中任何一个被定义在一个对象中,这个对象就是一个描述符。

注意,只有在新式类中描述符才会起作用(新式类继承type或者object class)

lazyproperty利用是属性访问的查找顺序

例如c.area->c.__dict__['area'] -> type(c).__dict__['area']  -> type(area)的基类

在第一次调用__get__之后,area的值存在c.__dict__['area'],已有缓存,因此不能再继续被赋值

class LazyProperty(object):  #描述符类
    """
    实现惰性求值(访问时才计算,并将值缓存)
    利用了 obj.__dict__ 优先级高于 non-data descriptor 的特性
    第一次调用 __get__ 以同名属性存于实例字典中,之后就不再调用 __get__
    """
    def __init__(self, fun):
        self.fun = fun

    def __get__(self, instance, owner):  #instance是实例
        if instance is None:
            return self
        value = self.fun(instance)
        setattr(instance, self.fun.__name__, value)
        return value


class ReadonlyNumber(object):
    """
    实现只读属性(实例属性初始化后无法被修改)
    利用了 data descriptor 优先级高于 obj.__dict__ 的特性
    当试图对属性赋值时,总会先调用 __set__ 方法从而抛出异常
    """
    def __init__(self, value):
        self.value = value

    def __get__(self, instance, owner):
        return self.value

    def __set__(self, instance, value):
        raise AttributeError(
            "'%s' is not modifiable" % self.value
         )


class Circle(object):

    pi = ReadonlyNumber(3.14)

    def __init__(self, radius):
        self.radius = radius

    @LazyProperty
    def area(self):
        return self.pi * self.radius ** 2

if __name__=="__main__":
    c = Circle(2)
    t = c.area
    print(t)
   
    c.radius = 3
    t = c.area
    print(t)

结果是:

3. @staticmethod  @classmethod

class A(object):
    def foo(self, x):
        print("executing foo(%s,%s)" % (self, x))
        print('self:', self)
    @classmethod
    def class_foo(cls, x):
        print("executing class_foo(%s,%s)" % (cls, x))
        print('cls:', cls)
    @staticmethod
    def static_foo(x):
        print("executing static_foo(%s)" % x)    
a = A()
a.foo(1)
A.class_foo(1)

A.static_foo(2)
a.static_foo(3)

 4. __str__()函数:

通过此函数可以帮助我们打印对象中的具体值,在python中调用print()打印实例化对象时会调用__str__(),如果__str__()有返回值,则会打印其中的返回值

class ss:
    def __init__(self,age,name):
        self.age = age
        self.name = name
    def __str__(self):
        return self.name +" is "+str(self.age)
if __name__=="__main__":
    s = ss(21,'ppp')
    print(s)

输出结果: ppp is 21

5. __new__():构造函数,静态函数

 __init__():初始化函数,实例函数,只能返回none

class Sample(object):

  def __new__(cls):
    print("Sample.__new__ called")
    return super().__new__(cls)
  
  def __init__(self):
    print("Sample.__init__ called")

s = Sample()

输出结果:

 6. __metaclass__ 与@abstractmethod

ABC(abstract base class)抽象基类,Python 对于ABC的支持模块是abc模块,定义了一个特殊的metaclass:ABCMeta 还有一些装饰器:@abstractmethod 和 @abstarctproperty 。abc.ABCMeta 用于在Python程序中创建抽象基类。而抽象基类如果想要声明“抽象方法”,可以使用 @abstractmethod ,如果想声明“抽象属性”,可以使用 @abstractproperty 

@abstractmethod严格控制子类必须实现这个方法,不然抛出异常

from abc import ABCMeta, abstractmethod
#python2写法
class AbstractFactory(object):
    """
    抽象工厂接口, 包含所有产品创建的抽象方法
    """
    __metaclass__ = ABCMeta

    @abstractmethod
    def create_product_a(self):
        pass

    @abstractmethod
    def create_product_b(self):
        pass

###python3写法
class AbstractFactory(metaclass=ABCMeta):
    """
    抽象工厂接口, 包含所有产品创建的抽象方法
    """
    @abstractmethod
    def create_product_a(self):
        pass

    @abstractmethod
    def create_product_b(self):
        pass

class ConcreteFactory1(AbstractFactory):
    """
    具体工厂, 创建具有特定实现的产品对象
    """

    def create_product_a(self):
        print("PA1")

    def create_product_b(self):
        print("PB1")

a = ConcreteFactory1()
a.create_product_a()

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!