当前位置: 首页 > news >正文

网站引导页分为三个板块设计风格移动互联网开发平台基于linux安卓

网站引导页分为三个板块设计风格,移动互联网开发平台基于linux安卓,域名绑定ip网站吗,自适应网站好建们1.魔法方法 Python中有一些特殊方法#xff0c;它们允许我们的类和Python更好地集成。在标准库参考#xff08;Standard Library Reference#xff09;中#xff0c;它们被称为魔法方法(Magic Methods)#xff0c;是与Python的其他特性无缝集成的基础。 例如#xff0c…1.魔法方法 Python中有一些特殊方法它们允许我们的类和Python更好地集成。在标准库参考Standard Library Reference中它们被称为魔法方法(Magic Methods)是与Python的其他特性无缝集成的基础。 例如我们用字符串来表示一个对象的值。Object 基类包含了__repr__() 和__str__() 的默认实现它们提供了一个对象的字符串描述。遗憾的是这些默认的实现不够详细。我们几乎总会想重写它们中的一个或两个。我们还会介绍__format__() 它更加复杂一些但是和上面两个方法的作用相同。 我们还会介绍其他的转换方法尤其是__hash__() 、__bool__() 和__bytes__() 。这些方法可以把一个对象转换成一个数字、一个布尔值或者一串字节。例如当我们实现了__bool__() 我们就可以像下面这样在if语句中使用我们的对象if someobject: 。 接下来我们会介绍实现了比较运算符的几个特殊方法__lt__() 、__le__() 、__eq__() 、__ne__() 、__gt__() 和__ge__() 。 当我们定义一个类时几乎总是需要使用这些基本的特殊方法。 我们会在最后介绍__new__() 和__del__() 因为它们的使用更加复杂而且相比于其他的特殊方法我们并不会经常使用它们。 我们会详细地介绍如何用这些特殊方法来扩展一个简单类。我们需要了解从object 继承而来的默认行为这样我们才能理解应该在什么时候使用重写以及如何使用它。 说白了就是对象的 我是谁我从哪里来到哪里去。 1.1__init__() 所有类的超类object有一个默认包含pass的__init__()实现这个函数会在对象初始化的时候调用我们可以选择实现也可以选择不实现一般建议是实现的不实现对象属性就不会被初始化虽然我们仍然可以对其进行赋值但是它已经成了隐式的了编程时显示远比隐式的更好 1.2__new__() __new__() 方法作为元类型的一部分主要是为了控制如何创建一个类。这和之前的如何用 __new__() 控制一个不可变对象是完全不同的。 一个元类型创建一个类。一旦类对象被创建我们就可以用这个类对象创建不同的实例。所有类的元类型都是type type() 函数被用来创建类对象。 另外type() 函数还可以被用作显示当前对象类型。 下面是一个很简单的例子直接使用 type() 作为构造器创建了一个新的但是几乎完全没有任何用处的类 Useless type(Useless,(),{})一旦我们创建了这个类我们就可以开始创建这个类的对象。但是这些对象什么都做不了因为我们没有定义任何方法和属性。 为了最大化利用这个类在下面的例子中我们使用这个新创建的Useless 类来创建对象。 Useless() __main__.Useless object at 0x101001910u_u.attr 1 dir(u) [__class__, __delattr__, __dict__, __dir__, __doc__, __eq__, __format__, __ge__, __getattribute__, __gt__, __hash__, __init__, __le__, __lt__, __module__, __ne__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, attr]我们可以向这个类的对象中增加属性。至少作为一个对象它工作得很好。 这样的类定义与使用types.SimpleNamespace 或者像下面这样定义一个类的方式几乎相同。 class Useless:pass1.3__repr__() __repr__() 和 __str__() 方法 对于一个对象Python提供了两种字符串表示。它们和内建函数repr() 、str() 、print() 及string.format() 的功能是一致的。 通常str() 方法表示的对象对用户更加友好。这个方法是由对象的__str__ 方法实现的。 repr() 方法的表示通常会更加技术化 这个方法是由__repr__() 方法实现的。 print() 函数会调用str() 来生成要输出的对象。字符串的format() 函数也可以使用这些方法。当我们使用{!r} 或者{!s} 格式时我们实际上分别调用了__repr__() 或者__str__() 方法。 下面我们先来看一下这些方法的默认实现。 直接打印对象的实现方法__str__ 是被print函数调用的一般都是return一个什么东西这个东西应该是以字符串的形式表现的。如果不是要用str()函数转换我们可以直接print的对象都是实现了__str__这个方法的比如dict。看下面的例子。 下面是一个很简单的类。 class RectAngle:def __init__(self, width, height):self.width widthself.height heightdef area(self):return self.width * self.heightdef __str__(self):return fRectAngle: {self.width}(w) * {self.height}(h)我们定义了两个简单类每个类包含4个属性。 下面是在命令行中使用RectAngle 类的结果。 rect RectAngle(4, 5)print(rect) RectAngle: 4(w) * 5(h)rect __main__.RectAngle object at 0x000002A1547E5A58可以看到__str__() print 方法打印的内容就看起来更加输入但是在命令行里面里面的调试信息还是现实的为对象当增加 __repr__() 方法之后调试信息也会变得更加清楚 def __repr__(self):return fRectAngle: w{self.width} h{self.height}在以下两种情况下我们可以考虑重写__str__() 和__repr__() 。 非集合对象 一个不包括任何其他集合对象的“简单”对象这类对象的格式化通常不会特别复杂。集合对象 一个包含集合的对象这类对象的格式化会更为复杂。 1.4__bool__() Python中有很多关于真假性的定义。参考手册中列举了许多和False 等价的值包括False 、0 、 、() 、[] 和{} 。其他大部分的对象都和True 等价。 通常我们会用下面的语句来测试一个对象是否“非空”。 if some_object:process( some_object )默认情况下这个是内置的bool() 函数的逻辑。这个函数依赖于一个给定对象的__bool__() 方法。 默认的__bool__() 方法返回True 。我们可以通过下面的代码来验证这一点。 x object()bool(x) True对大多数类来说这是完全正确的。大多数对象都不应该和False 等价。但是对于集合这样的行为并不总是正确的。一个空集合应该和False 等价而一个非空集合应该返回True 。或许应该给我们的Deck 集合对象增加一个类似的方法。 如果我们在封装一个列表我们可能会写下面这样的代码。 def __bool__(self):return bool(self.area)这段代码将__bool__() 的计算委托给了内部的函数area 。 现在我们就可以像下面这样使用Deck 。 r RectAngle(4, 5)if r:print(r)2.比较运算符方法 Python有6个比较运算符。这些运算符分别对应一个特殊方法的实现。根据文档运算符和特殊方法的对应关系如下所示。 x y 调用x.__gt__(y) 。 x y 调用x.__ge__(y) 。 x y 调用x.__lt__(y) 。 x y 调用x.__le__(y) 。x y 调用x.__eq__(y) 。x ! y 调用x.__ne__(y) 。 对于实际上使用了哪个比较运算符还有一条规则。这些规则依赖于作为左操作数的对象定义需要的特殊方法。如果这个对象没有定义Python会尝试改变运算顺序。 下面是两条基本的规则 首先运算符的实现基于左操作数A B相当于A.__lt__(B) 。 其次相反的运算符的实现基于右操作数A B相当于B.__gt__(A) 。 如果右操作数是左操作数的一个子类那这样的比较基本不会有什么异常发生同时Python会首先检测右操作数以确保这个子类可以重载基类。 下面我们通过一个例子看看这两条规则是如何工作的我们定义了一个只包含其中一个运算符实现的类然后把这个类用于另外一种操作。 下面是我们使用类中的一段代码。 class RectAngle:def __init__(self, width, height):self.width widthself.height heightdef area(self):return self.width * self.heightdef __gt__(self, other):# other 是另外一个对象return self.area() self.area()这段代码基于 RectAngle(矩形) 的比较规则主要是对比三角形的大小。 我们省略了比较方法看看当缺少比较运算符时Python将如何回退。这个类允许我们进行比较。但是有趣的是通过改变操作数的顺序Python也可以使用这个类进行比较。换句话说x y 和y x 是等价的。这遵从了镜像反射法则 当我们试图评估不同的比较运算时就会看到这种现象。下面我们创建两个RectAngle 类然后用不同的方式比较它们。 r1 RectAngle(4, 5)r2 RectAngle(5, 6)r1 r2 Truer1 r2 Falser1 r2 False从代码中我们可以看到r1 r2 调用了r1.__lt__(three) 。 但是对于r1 three 由于没有定义__gt__() Python使用r2.__lt__(two) 作为备用的比较方法。 默认情况下__eq__() 方法从object 继承而来它比较不同对象的ID值。当我们用于或!比较对象时结果如下。 r1_2 RectAngle(4, 5)r1_2 r1 False可以看到结果和我们预期的不同。所以我们通常都会需要重载默认的__eq__() 实现。 此外逻辑上不同的运算符之间是没有联系的。但是从数学的角度来看我们可以基于两个运算符完成所有必需的比较运算。Python没有实现这种机制。相反Python默认认为下面的4组比较是等价的。 x  y ≡ y  x x ≤ y ≡ y ≥ x x  y ≡ y  x x ≠ y ≡ y ≠ x 这意味着我们必须至少提供每组中的一个运算符。例如我可以提供__eq__() 、__ne__() 、__lt__() 和__le__() 的实现。 2.1比较运算 当设计比较运算符时要考虑两个因素。 如何比较同一个类的两个对象。如何比较不同类的对象。 对于一个有许多属性的类当我们研究它的比较运算符时通常会觉得有很明显的歧义。或许这些比较运算符的行为和我们的预期不完全相同。 2.2同类比较 下面我们通过一个更完整的RectAngle 类来看一下简单的同类比较。 # encoding:utf-8 class RectAngle:def __init__(self, width, height):self.width widthself.height heightdef area(self):return self.width * self.heightdef __lt__(self, other):return self.area() other.area()def __le__(self, other):return self.area() other.area()def __gt__(self, other):# other 是另外一个对象return self.area() other.area()def __ge__(self, other):return self.area() other.area()def __eq__(self, other):return self.area() other.area()def __ne__(self, other):return self.area() ! other.area()r1 RectAngle(4, 5) r2 RectAngle(5, 6)print(r1 r2) print(r1 r2)现在我们定义了6个比较运算符。 我们也没有给出类内比较的代码这个我们会在下一个部分中详细讲解。用上面定义的这个类我们可以成功地比较不同的牌。下面是一个创建并比较3张牌的例子。 r1 RectAngle(4, 5)r2 RectAngle(5, 6)r3 RectAngle(4, 6)用上面定义的RectAngle 类我们可以进行像下面这样的一系列比较。 r1 r2 Falser1.width r3.width Truer1 r3 False这个类的行为与我们预期的一致。 2.3不同类比较 我们会继续以RectAngle 类为例来看看当两个比较运算中的两个操作数属于不同的类时会发生什么。新增一个三角形对象 class Triangle:def __init__(self, width, height):self.width widthself.height heightdef area(self):return self.width * self.height / 2def __lt__(self, other):return self.area() other.area()def __eq__(self, other):return self.area() other.area()下面我们将一个RectAngle 实例和一个Triangle 值进行比较。 r1 RectAngle(4, 5)t1 Triangle(4, 5)r1 t1r1 t1 Traceback (most recent call last):File stdin, line 1, in module TypeError: unsupported operand type(s) for : RectAngle and Triangle可以看到这和我们预期的行为一致RectAngle 的子类Triangle 没有实现必需的特殊方法所以产生了一个TypeError 异常。 3.__call__() 该方法的功能类似于在类中重载 () 运算符使得类实例对象可以像调用普通函数那样以“对象名()”的形式使用。 class Example:def __call__(self, *args, **kwargs):return hello world !e Example()print(e) print(e()) 4.__del__() 方法 __del__() 方法有一个让人费解的使用场景。 这个方法的目的是在将一个对象从内存中清除之前可以有机会做一些清理工作。对于Python的垃圾回收机制而言创建一个上下文比使用 __del__() 更加容易预判。 但是如果一个Python对象包含了一些操作系统的资源__del__() 方法是把资源从程序中释放的最后机会。例如引用了一个打开的文件、安装好的设备或者子进程的对象如果我们将资源释放作为__del__() 方法的一部分实现那么我们就可以保证这些资源最后会被释放。 很难预测什么时候 __del__() 方法会被调用。它并不总是在使用del 语句删除对象时被调用当一个对象因为命名空间被移除而被删除时它也不一定被调用。Python文档中用不稳定来描述 __del__() 方法的这种行为并且提供了额外的关于异常处理的注释运行期的异常会被忽略相对地会使用 sys.stderr 打印一个警告。 基于上面的这些原因通常更倾向于使用上下文管理器而不是实现 __del__() 。 4.1 引用计数和对象销毁 CPython的实现中对象会包括一个引用计数器。当对象被赋值给一个变量时这个计数器会递增当变量被删除时这个计数器会递减。当引用计数器的值为0时表示我们的程序不再需要这个对象并且可以销毁这个对象。对于简单对象当执行删除对象的操作时会调用 __del__() 方法。 对于包含循环引用的复杂对象引用计数器有可能永远也不会归零这样就很难让 __del__() 被调用。 我们用下面的一个类来看看这个过程中到底发生了什么。 class RectAngle:def __init__(self, width, height):self.width widthself.height heightdef __del__(self):print(被删除 {0}.format(id(self))) 我们可以像下面这样创建和删除这个对象。 p RectAngle(4, 5)del p 被删除 2643407508256我们先创建然后删除了Noisy 对象几乎是立刻就看到了__del__() 方法中输出的消息。这也就是说当变量x 被删除后引用计数器正确地归零了。一旦变量被删除就没有任何地方引用Noisy 实例所以它也可以被清除。 下面是浅复制中一种常见的情形。 ln [RectAngle(4, 5), RectAngle(4, 6)]ln2 ln.copy()del lnPython没有响应del 语句。这说明这些Noisy 对象的引用计数器还没有归零肯定还有其他地方引用了它们下面的代码验证了这一点。 del ln2 被删除 2643407508592 被删除 26434075084804.2 循环引用和垃圾回收 下面是一种常见的循环引用的情形。一个父类包含一个子类的集合同时集合中的每个子类实例又包含父类的引用。 下面我们用这两个类来看看循环引用。 class Parent:def __init__(self, *children):self.children list(children)for child in self.children:child.parent selfdef __del__(self):print(删除 {} {}.format(self.__class__.__name__, id(self)))class Child:def __del__(self):print(删除 {} {}.format(self.__class__.__name__, id(self)))一个Parent 的instance 包括一个children 的列表。 每一个Child 的实例都有一个指向Parent 类的引用。当向Parent 内部的集合中插入新的Child 实例时这个引用就会被创建。 我们故意把这两个类写得比较复杂所以下面让我们看看当试图删除对象时会发生什么。 p Parent(Child(), Child())id(p) 2643407508984del pParent 和它的两个初始Child 实例都不能被删除因为它们之间互相引用。 下面我们创建一个没有Child 集合的Parent 实例。 p Parent()id(p) 2643407509096del p 删除 Parent 2643407509096和我们预期的一样这个Parent 实例成功地被删除了。 许多基本的特殊方法它们是我们在设计任何类时的基本特性。这些方法已经包含在每个类中只是它们的默认行为不一定能满足我们的需求。 我们几乎总是需要重载__repr__() 、__str__() 。这些方法的默认实现不是非常有用。 我们几乎不需要重载__bool__() 方法除非我们想自定义集合。这是第6章“创建容器和集合”的主题。 我们常常需要重载比较运算符。默认的实现只适合于比较简单不可变对象但是不适用于比较可变对象。我们不一定要重写所有的比较运算符 另外两个较为特殊的方法__new__() 和__del__() 有更特殊的用途。大多数情况下使用__new__() 来扩展不可变类型。 基本的特殊方法和__init__() 方法几乎会出现在我们定义的所有类中。其他的特殊方法则有更特殊的用途它们分为6个不同的类别。 属性访问 这些特殊方法实现的是表达式中object.attribute 的部分它通常用在一个赋值语句的左操作数以及del 语句中。可调用对象 一个实现了将函数作为参数的特殊方法很像内置的len() 函数。集合 这些特殊方法实现了集合的很多特性包括sequence[index] 、mapping[index] 和set | set 。数字 这些特殊方法提供了算术运算符和比较运算符。我们可以用这些方法扩展Python支持的数值类型。上下文 有两个特殊方法被我们用来实现可以和with 语句一起使用的上下文管理器。迭代器 有一些特殊方法定义了一个迭代器。没有必要一定要使用这些方法因为生成器函数很好地实现了这种特性。但是我们可以了解如何实现自定义的迭代器。 5. 重要的魔法方法 下面的表格列出了 Python 3中的重要魔法方法。 初始化和构建描述__new__(mcs, other)在对象的实例化中被调用__init__(self, other)使用 __new__ 调用__del__(self)删除方法 一元运算符和函数描述__pos__(self)正数__neg__(self)- 负数__abs__(self)abs() 函数__invert__(self)~ 操作符__round__(self,n)round() 取整__floor__(self)math.floor() 函数__ceil__(self)math.ceil() 函数__trunc__(self)math.trunc() 函数 增强赋值描述   __iadd__(self, other)__isub__(self, other)-__imul__(self, other)*__ifloordiv__(self, other)//__idiv__(self, other)a /b__itruediv__(self, other)__imod__(self, other)%__ipow__(self, other)**__ilshift__(self, other)__irshift__(self, other)__iand__(self, other)__ior__(self, other)|__ixor__(self, other)^ 类型转化魔法方法描述__int__(self)int()方法调用来将类型转换为int__float__(self)float()方法调用以将类型转换为float__complex__(self)Tcomplex() 方法调用以将类型转换为 complex__oct__(self)oct() 方法调用以将类型转换为八进制__hex__(self)hex() 方法调用以将类型转换为十六进制__index__(self)在切片中自动调用__trunc__(self)math.trunc ()方法调用 字符串魔法方法         描述__str__(self)str()方法调用以返回类型的字符串表示形式__repr__(self)repr()方法调用以返回类型的机器可读表示形式__unicode__(self)unicode() 方法调用以返回类型的 unicode 字符串__format__(self, formatstr)string.format() 方法调用以返回一个新样式的字符串__hash__(self)hash() 方法调用以返回整数__nonzero__(self)bool() 方法调用以返回 True 或 False__dir__(self)dir() 方法调用以返回类的属性列表__sizeof__(self)sys.getsizeof()方法调用以返回对象的大小 属性操作魔法方法描述__getattr__(self, name)当类的访问属性不存在时调用__setattr__(self, name, value)在为类的属性赋值时调用__delattr__(self, name)在删除类的属性时调用 运算魔法方法描述__add__(self, other)使用 运算符在比较时调用__sub__(self, other)使用 - 运算符在比较时调用__mul__(self, other)使用 * 运算符在比较时调用__floordiv__(self, other)使用 // 运算符在比较时调用__divmod__(self, other)使用 / 运算符在比较时调用__mod__(self, other)使用 % 运算符在比较时调用__pow__(self, other[, modulo])使用 ** 运算符在比较时调用__lt__(self, other)使用 运算符在比较时调用__le__(self, other)使用 运算符在比较时调用__eq__(self, other)使用 运算符在比较时调用__ne__(self, other)使用 ! 运算符在比较时调用__ge__(self, other)使用 运算符在比较时调用 因此您可以使用适当的魔法方法在自定义类中添加各种功能。
http://www.pierceye.com/news/696657/

相关文章:

  • html5写的网站有什么好处淄博网站制作制作
  • 服装设计素材网站大全做旅游的网站的要素
  • 企业网站建设报价清单深圳小程序建设公司
  • 给人做传销网站开发平台软件要多少钱
  • 腾讯建设网站视频视频视频手机网站报价表
  • 门户网站建设要求南京seo公司教程
  • 网站建设制作要学什么软件福建省城乡建设厅网站
  • 网站遇到攻击时应该怎么做网络广告推广平台
  • 老牌网站建深圳市建设工程服务交易中心
  • 网页界面设计布局青岛百度关键词优化
  • 彩票网站APP建设seo为什么不景气了
  • ps做网站标签wordpress 角色和权限管理
  • 网站建设情况报告范文微网站可以做成域名访问
  • 增城网站公司电话西安高端网站建设首选
  • 信息流广告素材网站零基础学做网站
  • 北京服饰网站建设实训百度搜索引擎的总结
  • 营销型网站建设的一般过程包括哪些环节?体育视频网站建设
  • 门户网网站seo怎么做电子商务平台怎么注册
  • 凡科网站插件代码阿里云网站备案后
  • 网站用什么系统好用免费网站建设找哪家
  • 网站到期续费吗网站开发是培训
  • 别人帮做的网站怎么修改怎么做产品推广和宣传
  • 国内返利网站怎么做php建设网站工具
  • 网站设计教程文档创业商机网农村
  • 宁夏交通建设质监局官方网站免费注册二级域名的网站
  • 网站门户设计网站建设有没有做的必要
  • 建模师的就业前景整站优化工具
  • 微信公众号怎么做链接网站网站404 原因
  • 安卓手机做服务器网站网站设计时多页面切换时什么控件
  • 长沙正规网站建设价格网站推广怎么发外链