一、魔法方法特点

  • 被双上下滑线包围
  • 魔法方法是面向对象的Python的一切,如果你不知道魔法方法,说明你还没能意识到面向对象的Python的强大(不是说Python脚本)
  • 通过对制定方法的重写,完全可以让python根据个人的用途去实现!

二、魔法方法

http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403


1、构造相关

__init__(self [,...])构造方法

  • 不写时,会默认存在一个无参的,写了会覆盖
  • 必须返回None,不能写 return,否则返回TypeError;因此不要对init做返回;

__new__(cls[, ...])

  • 对象实例化时调用的第一个方法,在init之前,它有个很大的不同第一个参数不是self,而是这个类cls,返回一个对象,cls后边的参数会原封不动的传给__init__()方法
  • 平时极少重写,当继承一个不可变类型又需要修改的时候,需要重写new
class CapStr(str):                #继承str类是不可变得
def __new__(cls, string):       #重写new,第一个传入class,叫其他名字也无所谓,只是为了区分
string = string.upper()      #全部变大写
return str.__new__(cls, string) 变完大写后,把它作为参数去调用基类的new方法 a = CapStr('I love Money')          #得到的a为大写

__del__(self)析构

  • delete缩写,当没有任何变量引用这个变量后,垃圾回收机制会自动销毁时调用它
  • 并非执行del x 就立马是调用x.__del__();


2、表现类

__str__        和print()对应

__repr__

>>> class A():
... def __str__(self):    #给print()用
... return "hahaha"
...
>>> a = A()
>>> a
<__main__.A object at 0x7f85993317f0>
>>> print(a)
hahaha

打印时,返回字符串,需要return 字符串,不可以是别的类型

__str__ = __repr__

>>> class A():
... def __repr__(self):    #给obj对象用
... return "hahaha"
...
>>> a = A()
>>> a
hahaha
>>> print(a)
hahaha
>>>

3、有关算数运算的魔法方法

在python2.2之前类和类型是分开的;类是属性和方法的封装;类型是像整型、浮点型、字符串等这些;但Python2.2之后,对二者进行统一,做法是将int、float、string、list、tuple等这些bif统统转化为工厂函数

int('123')在以前是调用int函数,把参数转化为整型;现在是用参数实例化一个int对象。并且对象可以做加法!

调用__add__(),因此可以重写,但重写没有多大意义吧

下边写法会进入无线递归:

改进:

推荐第一种写法

上表中的魔法方法加上r,就是反运算符:a + b,如果a对象的add方法没有实现或者不支持相应的操作的时候,那么python就会自动找到对象b的__radd__(self, other)方法

1为什么没有__add__()方法??

在减法中,为了实现目的,可以修改为 def __radd__(self, other):  return int.__sub__(other, self)

一元操作符

__neg__(self)         定义正号的行为:+x

__pos__(self)          定义符号的行为:-x

__abs__(self)          定义当被abs()调用时的行为

__invert__(self)       定义按位取反的行为:~x


4、属性访问

点;bif

__getattr__(self, name)

  • 定义当用户试图获取一个不存在的属性时的行为

__getattribute__(self, name)

  • 定义当该类的属性被访问时的行为

__setattr__(self, name, value)

  • 定义当一个属性被设置时的行为

__delattr__(self, name)

  • 定义当一个属性被删除时的行为
>>> class C:
... def __getattribute__(self, name):
... print("getattribute")
... return super().__getattribute__(name)
... def __getattr__(self, name):
... print("getattr")
... def __setattr__(self, name, value):
... print("setattr")
... super().__setattr__(name, value)
... def __delattr__(self, name):
... print("delattr")
... super().__delattr__(name)
...
>>> c = C()
>>> c.x
getattribute
getattr
>>> c.x = 1
setattr
>>> c.x
getattribute
1
>>> del c.x
delattr

定义一个矩形类,且修改__setattr__()方法,如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,宽和高等于边长。

  1 class Rextangle():
2 def __init__(self, width=0, height=0):
3 self.width = width
4 self.height = height
5
6 def __setattr__(self, name, value):
7 if name == 'square':
8 self.width = value
9 self.height = value
10 else:
11第一种 self.width = value    #报错,无限递归
12 self.height = value    #报错,无限递归
  第二种    self.name = value     #报错,无限递归
  第三种    super().__setattr__(name, value)  #正确(推荐)
  第四种    self.__dict__[name] = value     #正确
13 def getArea(self):
14 return self.width * self.height r = Rectangle(4, 5)    初始化是,有self.width\self.height赋值,回去调用被改写了的__setattr__()方法
r.getArea()        返回20
r.square = 10
r.width r.height   返回10
r.getArea()        返回100
r.__dict__         返回{'width':10, 'height':10}  因此会有“第四种”

5、描述符

描述符就是将某种特殊类型的类的实例指派给另一个类的属性。

  • __get__(self, instance, owner)    用于访问属性时调用,它返回属性值
  • __set__(self, instance, value)     将在属性分配操作中调用,不返回任何内容
  • __delete__(self, instance)              控制删除操作,不返回任何内容

这三个方法跟4里的属性访问方法很相似:python中__get__,__getattr__,__getattribute__的区别:主要看例子

  1 class MyDecriptor():
2 def __get__(self, instance, owner):
3 print("getting...", self, instance, owner)
4
5 def __set__(self, instance, value):
6 print("setting...", self, instance, value)
7
8 def __delete__(self, instance):
9 print("deleting...", self, instance) In [51]: class Test():
...: x = MyDecriptor()         #将类的实例指派给Test类的属性x,此时MyDecriptor()实例里的属性、方法就是x的描述符
...: In [52]: test = Test()              #实例化Test类 In [53]: test.x                  #调用了描述符的__get__()
getting... <yu412.MyDecriptor object at 0x7fa160356dd8> <__main__.Test object at 0x7fa1602a4f98> <class '__main__.Test'> In [54]: test                    #实例
Out[54]: <__main__.Test at 0x7fa1602a4f98> In [55]: Test                    #类
Out[55]: __main__.Test In [56]: test.x = "X-man"             #调用__set__()          
setting... <yu412.MyDecriptor object at 0x7fa160356dd8> <__main__.Test object at 0x7fa1602a4f98> X-man In [57]: del test.x                 #调用__delete__()
deleting... <yu412.MyDecriptor object at 0x7fa160356dd8> <__main__.Test object at 0x7fa1602a4f98>

利用以上原理可以轻松实现property()方法

练习:

先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性;要求两个属性会自动进行转换,也就是说你可以给摄氏度这个属性赋值,然后打印的华氏度属性是自动转换后的结果


6、定制容器

http://www.cnblogs.com/daduryi/p/6737186.html

_len__()、__getitem__()、__setitem__()和__delitem__()

__iter__()——返回迭代器本身

__next__()——决定迭代器的规则

python:类3——魔法方法的更多相关文章

  1. python类之魔法方法

    python类之魔法方法: class A(object): def __init__(self,x): self.x = x def __neg__(self): print('-v') def _ ...

  2. python day 11: 类的补充,元类,魔法方法,异常处理

    目录 python day 11 1. 类的补充 1.1 通过反射来查找类,创建对象,设置对象的属性与方法 1.2 类的魔法方法:getitem,setitem 1.3 元类__metaclass__ ...

  3. python里的魔法方法1(构造与析构)

    魔法方法——构造与析构 1.python编程的魔法方法: (1)魔法方法总是被双下划线包围,例如__init__: (2)魔法方法是面向对象的python的一切. 2.__new__(class[,… ...

  4. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  5. Python学习笔记之面向对象编程(三)Python类的魔术方法

    python类中有一些方法前后都有两个下划线,这类函数统称为魔术方法.这些方法有特殊的用途,有的不需要我们自己定义,有的则通过一些简单的定义可以实现比较神奇的功能 我主要把它们分为三个部分,下文也是分 ...

  6. 第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解

    第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解 一.    引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类 ...

  7. Python中的魔法方法

    1.什么是魔法方法? 魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一 ...

  8. Python 类的魔术方法

    Python中类的魔术方法 在Python中以两个下划线开头的方法,__init__.__str__.__doc__.__new__等,被称为"魔术方法"(Magic method ...

  9. python基础之魔法方法

    由于hexo自带的markdown渲染引擎对双下划线做了转义,在正文中看到的魔法方法前后都没有双下划线 setattr.getattr.delattr 可以拦截对对象属性的访问 setattr函数是用 ...

随机推荐

  1. 说说Object类下面有几种方法呢?

    今天说一道基础题型,不过很多人会忽略或者至少说不完整,但是面试时被问到的几率还是很大的. 面试题 Object有几种方法呢? Java语言是一种单继承结构语言,Java中所有的类都有一个共同的祖先.这 ...

  2. Mongoose-modified-at 时间自动记录插件介绍

    Mongoose-modified-at 是一款自动更新字段变化时间并记录到数据库中的 Mongoose 插件,类似 Mongoose 自带的 timestamps 功能. 使用场景 让我们考虑一个场 ...

  3. 去除img下方的空白(vertical-align:middle)——原理

    代码如下:一个简单的div装在一个img中, 然而在预览时却发现这种情况 也就是说img下方会无缘无故出现一个空隙.然后你发现,只要给img元素加上一个属性 vertical-align:middle ...

  4. win32API多线程编程

    win32线程API 在Windows平台下可以通过Windows的线程库来实现多线程编程. 对于多线程程序可以使用Visual Studio调试工具进行调试,也可以使用多核芯片厂家的线程分析调试工具 ...

  5. 开发架构+osi七层协议+socket(day26)

    目录 软件开发架构 C/S架构 B/S架构 网络编程 互联网协议/OSI七层协议 传输层 网络层 数据链路层 物理连接层 socket 什么是socket 为什么用socket 如何使用 软件开发架构 ...

  6. video3

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. deepin15.5 安装tensorflow-gpu

    deepin的CUDA和cuDNN安装方法与其它系统有所不同,参考其它操作系统的方法也许不适用,特别是显卡驱动的安装,容易使系统出现问题 本次配置: 操作系统:deepin15.5桌面版 电脑品牌:联 ...

  8. 使用ASP.NET Core 3.x 构建 RESTful API - 1.准备工作

    以前写过ASP.NET Core 2.x的REST API文章,今年再更新一下到3.0版本. 先决条件 我在B站有一个非常入门的ASP.NET Core 3.0的视频教程,如果您对ASP.NET Co ...

  9. [考试反思]1009csp-s模拟测试66:依旧

    依旧是好一场烂一场. 依旧是那么菜. 依旧是难止颓废. 依旧是在此方仰望,幻想? 上面这段中二的东西是为了防止Parisb说我的标题与内容无关而diss我莫名其妙115的语文. 但是菜是的确是菜... ...

  10. Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示

    目录管理命令ls:列出指定目录下的内容格式: ls [OPTION]... [FILE]...   -a:显示所有文件包括隐藏文件   -A:显示除.和..之外的所有文件   -l,--long:显示 ...