zoukankan      html  css  js  c++  java
  • python 面向对象编程 魔法方法

    魔法方法

    一、构造和初始化

    1、new

    new 方法,当使用类名(实参)创建实例对象市,python解析器的主要处理过程包括俩大类:1、调用特殊方法__new__()创建实例对象,首先会查找该类对象是否实现了此特殊方法,如果没有实现,则去其父类中查找,知道类对象object。2、调用 init() 此方法对创建的实例对象进行初始化 new() 返回的实例对象会作为实参自动传递给 init()的第一个形参self

    class Parent(object):
       def __new__(cls, *arg, **kwargs):
           print("父类的__new__被调用,其形参cls对应的id:",id(cls))
           obj = super().__new__(cls)
           print("创建的实例对象的id:",id(obj))
           return obj
    class Child(Parent):
       def __init__(self, name):
       #__new__返回的obj会作为实参传递给__init__的第一个形参self
           print("子类的__init__()被调用,其形参self对应的id:",id(self))
           self.name = name
    child = Child("Mike")
    
    

    二、属性访问控制

    2.1 getattr(self, name)

    2.2 setattr(self, name, value)

    2.3 delattr(self, name)

    2.4 getattribute(self, name)

    2.5 __

    三、描述器对象

    3.1 get

    3.2 set

    3.3 delete

    四、构造自定义容器

    功能 说明
    自定义不可变容器类型 需要定义__len__和__getitem__方法
    自定义可变类型容器 在不可变容器类型的基础上增加定义__setitem__ 和 delitem
    自定义的数据类型需要迭代 需要定义__iter__
    返回自定义容器的长度 需要实现__len__(self)
    自定义容器可以调用self[key],如果key类型错误,抛出TypeError,如果没法返回key对应的数值时,该方法应该抛出ValueError 需要实现__getitem__(self,key)
    当执行 self[key] = value 时 调用时 setitem(self, key, value)这个方法
    当执行 del self[key] 方法 其实调用的方法时 delitem(self, key)
    当你想你的容器可以执行for x in container 或者使用 iter(container) 需要实现__iter__(self), 该方法返回的是一个迭代器
    class FunctionalList:
        ''' 实现了内置类型list的功能,并丰富了一些其他方法: head, tail, init, last, drop, take'''
        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):
            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):
            # 获取所有元素,除了前N个
            return self.values[n:]
        def take(self, n):
            # 获取前N个元素
            return self.values[:n]
    

    4.1 len(self)

    4.2 getitem(self, key)

    五、操作符

    5.1 比较操作符

    5.1.1 cmp(self, other)

    5.1.2 eq(self, other)

    5.1.3 ne(self, other)

    5.1.4 it(self, other)

    5.1.5 gt(self, other)

    定义大于等于操作符(>)的行为。

    5.2 数值操作符

    5.2.1 一元操作符

    5.2.2 算数操作符

    六、上下文管理器

    6.1 enter(self)

    定义使用 with 声明创建的语句快嘴开始上下文管理器应该做些什么。注意 enter 的返回值会赋值给 with 声明的目标, 也就是 as 之后的东西。

    6.2 exit(self, exception_type, exception_value, traceback)

    定义当 with 声明语句块执行完毕(或终止)时上下文管理器的行为。它可以用来处理异常,进行清理,或者做其他应该在语句块结束之后立刻执行的工作。如果语句块顺利执行, exception_type, exception_value 和 traceback 会是None。否则,你可以选择处理这个异常或者让用户来处理。如果你想要处理异常,确保 exit 在完成工作之后返回 True。如果你不想处理异常,那就让它发生吧。 对一些具有良好定义的且通用的设置和清理行为的类,enterexit 会显得特别有用。你也可以使用这几个方法来创建通用的上下文管理器,用来包装其他对象。

    class Closer:
        '''一个上下文管理器,可以在with语句中
        使用close()自动关闭对象'''
    
        def __init__(self, obj):
            self.obj = obj
    
        def __enter__(self, obj):
            return self.obj # 绑定到目标
    
        def __exit__(self, exception_type, exception_value, traceback):
            try:
                    self.obj.close()
            except AttributeError: # obj不是可关闭的
                    print 'Not closable.'
                    return True # 成功地处理了异常
    
    这是一个 Closer 在实际使用中的例子,使用一个FTP连接来演示(一个可关闭的socket):
    
    >>> from magicmethods import Closer
    >>> from ftplib import FTP
    >>> with Closer(FTP('ftp.somesite.com')) as conn:
    ...         conn.dir()
    ...
    # 为了简单,省略了某些输出
    >>> conn.dir()
    # 很长的 AttributeError 信息,不能使用一个已关闭的连接
    >>> with Closer(int(5)) as i:
    ...         i += 1
    ...
    Not closable.
    >>> i
    6
    

    看到我们的包装器是如何同时优雅地处理正确和不正确的调用了吗?这就是上下文管理器和魔法方法的力量。Python标准库包含一个 contextlib 模块,里面有一个上下文管理器 contextlib.closing() 基本上和我们的包装器完成的是同样的事情(但是没有包含任何当对象没有close()方法时的处理)。

    本文内容链接

  • 相关阅读:
    虚方法与非虚方法,native关键字
    Java多态
    Java对象初始化顺序
    继承、初始化
    递归,斐波那契,对象类型数组
    方法重载
    可变形参
    idea
    ss 如何解决margin-top使父元素margin失效
    js中call和apply的用法和区别
  • 原文地址:https://www.cnblogs.com/guozepingboke/p/12794820.html
Copyright © 2011-2022 走看看