zoukankan      html  css  js  c++  java
  • python设计模式之内置装饰器使用(四)

    前言

    python内部有许多内建装饰器,它们都有特别的功能,下面对其归纳一下。

    系列文章

    python自带装饰器

    staticmethod

    staticmethod装饰器的功能是去除类的方法默认第一个参数是类的实例,使得该方法成为一个普通的函数,staticmethod是一个类,属于类装饰器。

    class Person(object):
        def eat(self):
            print('eat thing')
    
        @staticmethod
        def go(): # 不再传递self
            print('go')
    

    classmethod

    类定义时,除了new方法外,其他定义的方法在调用时第一个参数传入的必须是一个实例,使用classmethod装饰器装饰后,方法的第一个参数是类对象;调用类方法不需要创建类的实例。classmethod也是一个类,所以classmethod是一个类装饰器。

    class Person(object):
        _num_ear = 2
    
        def eat(self):
            print('eat thing')
    
        @classmethod
        def go(cls):
            print(cls._num_ear)
            print('go')
    
    if __name__ == '__main__':
        Person.go() # 无需创建实例,直接调用。
    

    property

    对于一个类的属性,python的访问是没有限制的,但有时候我们需要对属性的访问加以限制,property装饰器就是干这个的。

    property是一个类,它有三个方法,deleter,setter,getter,有两种使用方式。

    class Person(Animal):
        _num_ear = 2
    
        def __init__(self):
            self._name = 'xiaoming'
            self.age = 20
    
        def get_name(self):
            print('get name')
            return self._name
    
        def set_name(self, name):
            print('set name')
            self._name = name
    
        def delete_name(self):
            print('del name')
            del self._name
    
        name = property(get_name, set_name, delete_name, doc='name of person')
        # 或使用匿名函数
        name = property(lambda self:self._name, lambda self, name: setattr(self, '_name', name), lambda self:delattr(self,'_name'))
    
    if __name__ == '__main__':
        p = Person()
        print(p.name) # 会调用get_name
        p.name = 'xxxx'  # 会调用set_name
        del p.name     # 会调用delete_name
    

    property可以手动指定限制的函数,有四个参数,但是这样显得比较麻烦,可以使用装饰器的形式。

    class Person(Animal):
        _num_ear = 2
    
        @property
        def name(self):
            return self._name
    
        @name.setter
        def name(self, nm):
            self._name = nm
    
        @name.deleter
        def name(self):
            del self._name
    
    if __name__ == '__main__':
        p = Person()
        print(p.name) 
        p.name = 'xxxx' 
        del p.name    
    

    一个函数被property装饰后返回的是property对象,只有fget参数的函数可以被property,因为装饰器只接受一个参数;另外的属性设置和删除需要直观调用响应的方法。

    abstractmethod

    python的抽象类和java不一样,java的抽象类不能实例化,同时抽象方法子类必须实现,否则报错!但是python抽象类默认是可以实例化的,也可以这样说,如果我们对抽象类定义:本身不能实例化,子类必须实现抽象方法;那么我们一般写的基类都不是抽象类。如果想要实现java中的抽象类的效果该怎么办呢?使用abstractmethod装饰器,含义是抽象方法。

    一个类中的任何方法被abstractmethod装饰后,这个类不能实例化并且子类必须实现被abstractmethod装饰的方法。

    from abc import abstractmethod,ABCMeta
    class Animal(metaclass=ABCMeta):
    
        @abstractmethod
        def eat(self):
            pass
    
    class Person(Animal):
        _num_ear = 2
        def eat(self):
            print('eat thing')
    
        @classmethod
        def go(cls):
            print(cls._num_ear)
            print('go')
    

    如果需要定义一个类是抽象类,那么它需要继承ABCMeta而不是object,这样abstractmethod装饰器才会起作用。其起作用的原理是将一个方法的__isabstractmethod__属性设置为True,这样解释器就会检查子类是否实现了抽象方法。

    总结

  • 相关阅读:
    good source
    走进科学之揭开神秘的零拷贝[z]
    git push 本地项目推送到远程分支[z]
    Hibernate配置(通过注解配置)
    Hibernate配置(外部配置文件方式)
    Oracle数据库中scott用户不存在的解决方法
    找滑动窗口的中位数
    Spring日期格式初始化
    Oracle对表空间无权限
    Oracle中默认创建的表
  • 原文地址:https://www.cnblogs.com/cwp-bg/p/9555201.html
Copyright © 2011-2022 走看看