Python Magic and Builtin Method

构造和初始化

  • __new__用来调用这个类,并返回这个类的实例
  • __init__只是将传入的参数来初始化该实例

控制属性访问

  • __getattr__(self, name):
    当用户视图获取一个不存在的属性时的行为。这适用于对普通拼写错误和重定向,对获取一些不建议的属性时,给予警告或者处理一个AttributeError。只有当调用不存在的属性时,会被返回。

  • __setattr__(self, name, value):
    一个封装的解决方案,无论属性值是否存在,它都允许你定义对属性赋值行为。实现__setattr__要避免无限的递归错误

# uncorrect
def __setattr__(self, name, value):
    self.name = value
    # 没当属性被赋值时,``__setattr__()``会被调用,这样就造成了递归调用。
    # 意味调用``self.__setattrr__('name', value)``,每次方法会调用自己,造成程序崩溃。
    
# correct
def __setattr__(self, name, value):
    self.__dict__[name] = value  # 给类中的属性分配值
    # 定制特有属性
  • __delattr__:
    删除一个属性,实现时要防止无限递归发生

创建自定义容器

Python容器类型:
可变类型: list, dict
不可变类型: stringtuple

  • __len__(self):返回容器长度。
  • __getitem__(self, key):当定义某一项被访问时,使用self[key]所产生的行为。
  • __setitem__(self, key, value):执行self[key] = value,调用该方法。
  • __delitem__(self):定义删除一个项目时的行为,如del self[key]
  • __iter__(self):返回一个容器迭代器。
  • __reversed__(self):实现当 reversed()被调用时的行为。
  • __contains__(self, item):定义调用innot in来测试成员是否在的时候产生的行为。
  • __missing__(self, key)dict类型会有该方法,它定义了key如果在容器中找不到时触发的行为。
class FunctionalList:
    '''实现内置list功能,并丰富一些其他用法'''
    
    def __init__(self, values=None):
        if values is None:
            self.values = []
        else:
            self.values = values
            
    def __len__(self):
        return len(self.values)
        
    def __getitem__(self, key):
        return self.values[key]
        
    def __setitem__(self, key, value):
        return self.values[key] = value
        
    def __delitem__(self, key):
        del self.values[key]

    def __iter__(self):
        return iter(self.values)
        
    def __reversed__(self):
        return FunctionalList(reversed(self.values))
        
    def append(self, value):
        self.values.append(value)
        
    def head(self):
        return self.values[0]
        
    def tail(self):
        return self.values[1:]
        
    def init(self):
        return self.values[:-1]
        
    def last(self):
        return self.values[-1]
        
    def drop(self, n):
        return self.values[n:]
        
    def task(self, n):
        return self.values[:n]

Python collections有很多类似的实现

反射

控制怎么使用内置函数 isinstance()和issubclass()方法,反射定义魔术方法:

  • __instancecheck__(self, instance)
    检查一个实例是不是你定义类的实例
  • __subclasscheck__(self, subclass)
    检查一个类是不是你定义类的子类

可调用对象

特殊的魔术方法可以让类的实例的行为表现像函数一样,可以调用它们,将一个函数当做参数传递到另外一个函数中等。

  • __call__(self, [args,...]):
    允许一个类的实例像函数一样被调用。这意味着x()x.__call__()是相同的。__call__的参数可变,可以定义它为你想要的函数。

__call__在那些类的实例经常改变状态的时候非常有效。调用这个实例是一种改变这个对象状态的直接和优雅的做法。

class Entity:
    '''调用实体来改变实体的位置'''
    
    def __init__(self, size, x, y):
        self.x, self.y = x, y
        self.size = size
        
    def __call__(self, x, y):
        '''改变实体位置'''
        self.x, self.y = x, y

上下文管理器

with声明的代码段中,可以做一些对象的开始操作和退出操作,还能对异常进行处理。需要实现两个魔术方法__enter____exit__

  • __enter__(self):
    定义了当声明with语句的时候,会话管理器在块被初始创建时产生的行为,__enter__的返回值与with语句的目标或者as后的名字绑定。
  • __exit__(self):
    定义了一个代码块被执行或者终止后,会话管理器应该做什么。可以被用来处理异常,执行清理工作或做一些代码块执行完毕后的日常。如果代码块执行成功,exception_type, exception_valuetraceback将为None。否则你可以选择处理这个异常,或者直接交给客户处理。如果你想处理这个异常,请确保__exit__所在的语句结束后返回True。如果你想让异常会话被管理器处理,那就让其产生异常。

创建对象描述器

描述器是通过获取、设置及删除的时候访问的类。描述器并不是独立的,它意味着被一个类所有者持有。当创建面向对象的数据库或者类,里面含有相互依赖的属性时,描述器将会非常有用。一种典型的用法用不同的单位表示数值,或者某个数据的附加属性。
一个描述器类至少应该包括:__get__,__set__,__delete__方法被实现:

  • __get__(self, instance, owner):
    定义描述器的值被取得时候的行为。instance是拥有该描述器对象的实例,owner是拥有者本身。

  • __set__(self, instance, value):
    定义描述器的值被改变时候的行为。instance是拥有该描述器对象的实例,value是要设置的值。

  • __delete__(self, instance):
    定义了描述器值被删除时的行为。instance是拥有该描述器对象的实例

描述器的实例,单位转换

class Meter(object):
    """单位'米'的描述器"""
    
    def __init__(self, value=0.0):
        self.value = float(value)
        
    def __get__(self, instance, owner):
        return self.value
        
    def __set__(self, instance, value):
        self.value = float(value)
        
class Foot(object):
    """单位'尺'的描述器"""
    
    def __get__(self, instance, owner):
        return instance.meter * 3.2808
        
    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808
        
class Distance(object):
    """用米和英寸表示两个描述器之间的距离"""
    meter = Meter(10)
    foot = Foot()

拷贝

  • __copy__(self):
    调用copy.copy()时产生的行为,返回你的对象的浅拷贝

  • __deepcopy__(self memdict={}):
    调用copy.deepcopy()时产生的行为,返回你的对象的深拷贝。memdict是对之前被拷贝对象的一个缓存----这优化了拷贝过程并且阻止了对递归数据结构拷贝时的无限递归。当你想要进行单独的属性进行拷贝时,调用copy.deepcopy(),并用memdict为第一个参数

你可能感兴趣的:(Python Magic and Builtin Method)