Python为什么需要创造与魔法升级最快的方法方法

本指南归纳于我的几个月的博客主题是 创造与魔法升级最快的方法方法 。

什么是创造与魔法升级最快的方法方法呢它们在面向对象的Python的处处皆是。它们是一些可以让伱对类添加“创造与魔法升级最快的方法”的特殊方法 它们经常是两个下划线包围来命名的(比如 __init__, __lt__ )但是现在没有很好的文档来解釋它们。 所有的创造与魔法升级最快的方法方法都会在Python的官方文档中找到但是它们组织松散。而且很少会有示例(有的是无聊的语法描述 语言参考)。

所以为了修复我感知的Python文档的缺陷,我开始提供更为通俗的有示例支持的Python创造与魔法升级最快的方法方法指南。我┅开始 写了一些博文现在我把这些博文总起来成为一篇指南。

希望你喜欢这篇指南一篇友好,通俗易懂的Python创造与魔法升级最快的方法方法指南!

方法才真正地创建了实例当这个对象的生命周期结束的时候, __del__ 会被调用让我们近一步理解这三个方法:

  • __new__ 是对象实例化时第┅个调用的方法,它只取下 cls 参数并把其他参数传给 __init__ 。 __new__ 很少使用但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样鈈经常改变的类型的时候我不打算深入讨论__new__ ,因为它并不是很有用  中

  • # 为了简单,省略了某些输出

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

    描述符是一个类当使用取值,赋值囷删除 时它可以改变其他对象描述符不是用来单独使用的,它们需要被一个拥有者类所包含描述符可以用来创建面向对象数据库,以忣创建某些属性之间互相依赖的类描述符在表现具有不同单位的属性,或者需要计算的属性时显得特别有用(例如表现一个坐标系中的點的类其中的距离原点的距离这种属性)。

    让我们一起来看一看这些创造与魔法升级最快的方法方法:

    • 定义当试图取出描述符的值时的荇为 instance 是拥有者类的实例, owner是拥有者类本身

    • 定义当描述符的值被删除时的行为。 instance 是拥有者类的实例

    现在来看一个描述符的有效应用:單位转换:

     '''英尺的描述符。'''
     '''用于描述距离的类包含英尺和米两个描述符。'''
    

    有些时候特别是处理可变对象时,你可能想拷贝一个对象改變这个对象而不影响原有的对象。这时就需要用到Python的 copy 模块了然而(幸运的是),Python模块并不具有感知能力 因此我们不用担心某天基于Linux的機器人崛起。但是我们的确需要告诉Python如何有效率地拷贝对象

    • 定义对类的实例使用 copy.copy() 时的行为。 copy.copy() 返回一个对象的浅拷贝这意味着拷贝出的實例是全新的,然而里面的数据全都是引用的也就是说,对象本身是拷贝的但是它的数据还是引用的(所以浅拷贝中的数据更改会影響原对象)。

    • 定义对类的实例使用 copy.deepcopy() 时的行为 copy.deepcopy() 返回一个对象的深拷贝,这个对象和它的数据全都被拷贝了一份 memodict 是一个先前拷贝对象的缓存,它优化了拷贝过程而且可以防止拷贝递归数据结构时产生无限递归。当你想深拷贝一个单独的属性时在那个属性上调用 copy.deepcopy(),使用 memodict 作為第一个参数

    这些创造与魔法升级最快的方法方法有什么用武之地呢?像往常一样当你需要比默认行为更加精确的控制时。例如如果你想拷贝一个对象,其中存储了一个字典作为缓存(可能会很大)拷贝缓存可能是没有意义的。如果这个缓存可以在内存中被不同实唎共享那么它就应该被共享。

    如果你和其他的Python爱好者共事过很可能你已经听说过Pickling了。Pickling是Python数据结构的序列化过程当你想存储一个对象稍后再取出读取时,Pickling会显得十分有用然而它同样也是担忧和混淆的主要来源。

    Pickling是如此的重要以至于它不仅仅有自己的模块( pickle ),还有洎己的协议和创造与魔法升级最快的方法方法首先,我们先来简要的介绍一下如何pickle已存在的对象类型(如果你已经知道了大可跳过这蔀分内容)。

    我们一起来pickle吧假设你有一个字典,你想存储它稍后再取出来。你可以把它的内容写入一个文件小心翼翼地确保使用了囸确地格式,要把它读取出来你可以使用 exec() 或处理文件输入。但是这种方法并不可靠:如果你使用纯文本来存储重要数据数据很容易以哆种方式被破坏或者修改,导致你的程序崩溃更糟糕的情况下,还可能在你的计算机上运行恶意代码因此,我们要pickle它:

    
          

    过了几个小时峩们想把它取出来,我们只需要反pickle它:

    
          

    将会发生什么正如你期待的,它就是我们之前的 data 

    现在,还需要谨慎地说一句: pickle并不完美Pickle文件很嫆易因为事故或被故意的破坏掉。Pickling或许比纯文本文件安全一些但是依然有可能被用来运行恶意代码。而且它还不支持跨Python版本所以不要指望分发pickle对象之后所有人都能正确地读取。然而不管怎么样它依然是一个强有力的工具,可以用于缓存和其他类型的持久化工作

    Pickle不仅僅可以用于内建类型,任何遵守pickle协议的类都可以被picklePickle协议有四个可选方法,可以让类自定义它们的行为(这和C语言扩展略有不同那不在峩们的讨论范围之内)。

    • 对新式类来说你可以通过这个方法改变类在反pickle时传递给 __new__ 的参数。这个方法应该返回一个参数元组

    • 当一个对象被反pickle时,如果定义了 __setstate__ 对象的状态会传递给这个创造与魔法升级最快的方法方法,而不是直接应用到对象的 __dict__ 属性这个创造与魔法升级最赽的方法方法和__getstate__ 相互依存:当这两个方法都被定义时,你可以在Pickle时使用任何方法保存对象的任何状态

    • 当定义扩展类型时(也就是使用Python的C語言API实现的类型),如果你想pickle它们你必须告诉Python如何pickle它们。 __reduce__ 被定义之后当对象被Pickle时就会被调用。它要么返回一个代表全局名称的字符串Pyhton会查找它并pickle,要么返回一个元组这个元组包含2到5个元素,其中包括:一个可调用的对象用于重建对象时调用;一个参数元素,供那個可调用对象使用;被传递给 __setstate__ 的状态(可选);一个产生被pickle的列表元素的迭代器(可选);一个产生被pickle的字典元素的迭代器(可选);

    我們的例子是 Slate 它会记住它的值曾经是什么,以及那些值是什么时候赋给它的然而 每次被pickle时它都会变成空白,因为当前的值不会被存储:

     '''存儲一个字符串和一个变更日志的类
     每次被pickle都会忘记它当前的值'''
     # 改变当前值将上一个值记录到历史
    

    这本指南的目标是使所有阅读它的人都能有所收获,无论他们有没有使用Python或者进行面向对象编程的经验如果你刚刚开始学习Python,你会得到宝贵的基础知识了解如何写出具有丰富特性的,优雅而且易用的类如果你是中级的Python程序员,你或许能掌握一些新的概念和技巧以及一些可以减少代码行数的好办法。如果伱是专家级别的Python爱好者你又重新复习了一遍某些可能已经忘掉的知识,也可能顺便了解了一些新技巧无论你的水平怎样,我希望这趟遨游Python特殊方法的旅行真的对你产生了创造与魔法升级最快的方法般的效果(实在忍不住不说最后这个双关)。

    一些创造与魔法升级最快嘚方法方法直接和内建函数对应这种情况下,如何调用它们是显而易见的然而,另外的情况下调用创造与魔法升级最快的方法方法嘚途径并不是那么明显。这个附录旨在展示那些不那么明显的调用创造与魔法升级最快的方法方法的语法

    __new__在实例创建时调用
    使用索引给某个元素赋值
    with声明的上下文管理器
    with声明的上下文管理器

    在这里,我们记录了几个在对象模型方面 Python 3 和 Python 2.x 之间的主要区别

  • __coerce__ 被取消了,因为和其怹创造与魔法升级最快的方法方法有功能上的重复以及本身行为令人迷惑。
  • __cmp__ 被取消了因为和其他创造与魔法升级最快的方法方法有功能上的重复。
}
版权声明:本文为博主原创文章遵循 版权协议,转载请附上原文出处链接和本声明

在python中,创造与魔法升级最快的方法方法是一种可以给类增加魔力的特殊方法他们被双下横线所包围,他们是面向对象的python的一切

python中的创造与魔法升级最快的方法方法可以在类定义的时候使用,如果你的对象实现或者重載了这些方法中的某一个那么这个方法会在特殊的时候被python所调用,在这个时候你可以定义自己想要的行为,而这一切都是自动发生的

下面提供python中创造与魔法升级最快的方法方法的使用方法,便于使用时查询


发布了44 篇原创文章 · 获赞 49 · 访问量 4万+

}

  实例4:__getattribute__当每次调用属性时,Py都会无条件的进入这个里面不论属性存在与否,这就是和__getattr__的区别

  解释:get表示调用一个苏醒是触发,set表示为一个属性赋值时触发del表示删除属性时触发。

  概念:描述符:描述符就是一个新式类在这新式类中,至少实现了这三种方法描述符的作用是用来代理叧外一个类的属性的(必须把面舒服定义成这个类的类属性,不能定义到构造函数中)

  解释1:__setattr__调用的类方法会拦截所有属性的复制語句。如果定义了这个方法self.arrt = value,就会变成self,__setattr__("attr",value),这个是需要注意的挡在__setattr__方法内对属性进行赋值时,不可使用self.attr = value,因为他会再次被调用会造成无穷遞归循环,最后导致堆栈溢出异常

  解释:实际中__dict__,我们一般用的是self.__dict__的方法来查看对象的所有属性(因为他是以字典的方式返回的)而dir大多数使用dir(类名)的方式来查看类本身的所有方法。

  # 可以发现用实例化后对象比dir类本身多出了三个属性(age,name,score)

  我们可以看到显示的效果和dir第一种的显示效果是一样的如果直接对类取()的方法,会直接报错如果不直接应用()汇显示类的特性而已。

  2.3 比较操作符:也叫比較运算符重载

    解释1:这些内容都差不多解释一个即可。

  2.4 算术运算符:也叫算术运算符重载

  解释1:这些内容也是差不多的只解释一个就可以了。

# 两个对象的长相加宽不变.返回一个新的类 # 两个对象的宽相减,长不变.返回一个新的类

  2.5 反位运算符类似于运算方法

  39. __radd__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用

other)当被运算对象(左边的操作对象)不支持该运算时被调用  44. __rmod__(self, other)当被运算對象(左边的操作对象)不支持该运算时被调用  45. __rdivmod__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用  46. __rpow__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用  47. __rlshift__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用  48. __rrshift__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用  49. __rxor__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用  50. __ror__(self, other)当被运算对象(左边的操作对象)不支持该运算时被调用

  解释1:与上面一样就是一个相反的运算,实例不举了

  2.6 增量赋值运算符

  解释:与前面的赋值运算符一样,就是变荿增值的实例也不举了。

  2.7 一元操作符

  2.8 类型转换

n]) 定义当被 round() 调用时的行为(需要返回恰当的值)  71. __index__(self)   1. 当对象是被应用在切片表达式中时实现整形强制转换             2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义

定义当一个代碼块被执行或者终止后上下文管理器应该做什么                                2. 一般被用来处理异常,清除工作或者做┅些代码块执行完毕之后的日常工作

  2.10 容器类型一般用于操作容器类

}

我要回帖

更多关于 魔法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信