Python魔术方法大全2

简介: 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”(魔术方法),例如类的初始化方法 init ,Python中所有的魔术方法均在官方文档中有相应描述,这边给大家把所有的魔术方法汇总了一下,希望对大家的学习有所帮助。

7. 一元操作符


image.png

8. 类型转换


image.png


9. 上下文管理(with 语句)


image.png

10. 容器类型


image.png

在Python中,所有以__双下划线包起来的方法,都统称为"魔术方法"。比如我们接触最多的__init__。 有些魔术方法,我们可能以后一辈子都不会再遇到了,这里也就只是简单介绍下; 而有些魔术方法,巧妙使用它可以构造出非常优美的代码,比如将复杂的逻辑封装成简单的API。


11. 构造和初始化


__init__我们很熟悉了,它在对象初始化的时候调用,我们一般将它理解为"构造函数".


实际上, 当我们调用x = SomeClass()的时候调用,__init__并不是第一个执行的, __new__才是。所以准确来说,是__new__和__init__共同构成了"构造函数".


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


new__在创建一个实例的过程中必定会被调用,但__init__就不一定,比如通过pickle.load的方式反序列化一个实例时就不会调用__init。


__new__方法总是需要返回该类的一个实例,而__init__不能返回除了None的任何值。比如下面例子:


class Foo(object):
    def __init__(self):
        print 'foo __init__'
        return None  # 必须返回None,否则抛TypeError
    def __del__(self):
        print 'foo __del__'


实际中,你很少会用到__new__,除非你希望能够控制类的创建。 如果要讲解__new__,往往需要牵扯到metaclass(元类)的介绍。


对于__new__的重载,Python文档中也有了详细的介绍。 在对象的生命周期结束时, __del__会被调用,可以将__del__理解为"析构函数".


__del__定义的是当一个对象进行垃圾回收时候的行为。 有一点容易被人误解, 实际上,x.del() 并不是对于del x的实现,但是往往执行del x时会调用x.del().


怎么来理解这句话呢? 继续用上面的Foo类的代码为例:


class Foo(object):
    def __init__(self):
        print 'foo __init__'
        return None  # 必须返回None,否则抛TypeError
    def __del__(self):
        print 'foo __del__'
foo = Foo()
foo.__del__()
print foo
del foo
print foo  # NameError, foo is not defined

如果调用了foo.del(),对象本身仍然存在. 但是调用了del foo, 就再也没有foo这个对象了.


请注意,如果解释器退出的时候对象还存在,就不能保证 del 被确切的执行了。所以__del__并不能替代良好的编程习惯。


比如,在处理socket时,及时关闭结束的连接。


12. 属性访问控制

总有人要吐槽Python缺少对于类的封装,比如希望Python能够定义私有属性,然后提供公共可访问的getter和 setter。Python其实可以通过魔术方法来实现封装。


12.1 getattr(self, name)

该方法定义了你试图访问一个不存在的属性时的行为。因此,重载该方法可以实现捕获错误拼写然后进行重定向, 或者对一些废弃的属性进行警告。


12.2 setattr(self, name, value)

setattr 是实现封装的解决方案,它定义了你对属性进行赋值和修改操作时的行为。


不管对象的某个属性是否存在,它都允许你为该属性进行赋值,因此你可以为属性的值进行自定义操作。有一点需要注意,实现__setattr__时要避免"无限递归"的错误,下面的代码示例中会提到。


12.3 delattr(self, name)

__delattr__与__setattr__很像,只是它定义的是你删除属性时的行为。实现__delattr__是同时要避免"无限递归"的错误。


12.4 getattribute(self, name)

__getattribute__定义了你的属性被访问时的行为,相比较,__getattr__只有该属性不存在时才会起作用。


因此,在支持__getattribute__的Python版本,调用__getattr__前必定会调用 getattribute。__getattribute__同样要避免"无限递归"的错误。


需要提醒的是,最好不要尝试去实现__getattribute__,因为很少见到这种做法,而且很容易出bug。


例子说明__setattr__的无限递归错误:



def __setattr__(self, name, value):
    self.name = value
    # 每一次属性赋值时, __setattr__都会被调用,因此不断调用自身导致无限递归了。

因此正确的写法应该是:


def __setattr__(self, name, value):
    self.__dict__[name] = value


__delattr__如果在其实现中出现del self.name 这样的代码也会出现"无限递归"错误,这是一样的原因。

下面的例子很好的说明了上面介绍的4个魔术方法的调用情况:


class Access(object):
    def __getattr__(self, name):
        print '__getattr__'
        return super(Access, self).__getattr__(name)
    def __setattr__(self, name, value):
        print '__setattr__'
        return super(Access, self).__setattr__(name, value)
    def __delattr__(self, name):
        print( '__delattr__')
        return super(Access, self).__delattr__(name)
    def __getattribute__(self, name):
        print( '__getattribute__')
        return super(Access, self).__getattribute__(name)
access = Access()
access.attr1 = True  # __setattr__调用
access.attr1  # 属性存在,只有__getattribute__调用
try:
    access.attr2  # 属性不存在, 先调用__getattribute__, 后调用__getattr__
except AttributeError:
    pass
del access.attr1  # __delattr__调用
目录
相关文章
|
2月前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
26 0
|
4月前
|
开发者 Python
Python教程:你一定要知道的26个Python魔术方法(快记下来)
Python中的魔术方法是指以双下划线 __ 开头和结尾的特殊方法,也被称为特殊方法或魔术方法。这些方法在类中具有特殊的用途,它们可以让你自定义类的行为,使得你的对象可以像内置类型一样工作。
35 3
|
5月前
|
数据库 Python
Python常见的魔术方法和魔术属性(一)
Python常见的魔术方法和魔术属性(一)
|
5月前
|
Python
Python常见的魔术方法和魔术属性(二)
Python常见的魔术方法和魔术属性(二)
|
5月前
|
Python
python基础篇:python面向对象有哪些魔术方法?具体有什么用?
python基础篇:python面向对象有哪些魔术方法?具体有什么用?
31 1
|
5月前
|
Java 程序员 索引
Python中魔术方法汇总
Python中魔术方法汇总
54 0
|
5月前
|
Python
Python高级专题 - 类型转换的魔术方法
Python高级专题 - 类型转换的魔术方法
40 1
|
5月前
|
Java Shell 程序员
Python 进阶指南(编程轻松进阶):十七、Python 风格 OOP:属性和魔术方法
Python 进阶指南(编程轻松进阶):十七、Python 风格 OOP:属性和魔术方法
40 0
|
5月前
|
存储 程序员 索引
python面向对象编程,什么是魔术方法(magic method),它们有什么作用?
python面向对象编程,什么是魔术方法(magic method),它们有什么作用?
120 0
|
11月前
|
Java PHP Python
小记Python中一些常用的魔术方法
小记Python中一些常用的魔术方法
38 0