__repr__

Python中这个__repr__函数,对应repr(object)这个函数,返回一个可以用来表示对象的可打印字符串.
如果我们直接打印一个类,向下面这样

class A():
    def __init__(self,name=None,id=1):
        self.id=id
        self.name=name if __name__ == '__main__':
    a=A()
    print(a)

输出结果

<__main__.A object at 0x0000018DF8E7EAC8>

不是很友好,返回了一个对象的内存地址。
我们改成下面再次输出

class A():
    def __init__(self,name=None,id=1):
        self.id=id
        self.name=name
    def __repr__(self):
        return "进入函数" if __name__ == '__main__':
    print(A())

输出结果

进入函数

__str__

class A():
    def __init__(self,name=None,id=1):
        self.id=id
        self.name=name
    def __str__(self):
        return "进入函数" if __name__ == '__main__':
    print(A())

输出结果

进入函数

比较repr和str

上面我们发现在print的时候,两个魔法函数显示的效果是一样的,那这两个魔法函数区别在哪呢,__repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员。在print的时候两者项目一样,但是在交互命令下
__repr__同样有着print的效果,但是__str__还是输出对象内存地址。也就说在交互式命令下我们可以看到其效果,另外__str__ 方法其实调用了 __repr__ 方法。

__getitem__

如果在类中定义了getitem__()方法,那么他的实例对象(假设为A)就可以这样A[key]取值。当实例对象做A[key]运算时,就会调用类中的__getitem()方法。

class A():
    def __init__(self,name=None,id=1):
        self.id=id
        self.name=name
    def __repr__(self):
        return "进入函数"
    def __getitem__(self, item):
       return item if __name__ == '__main__':
    a=A('lisa','123')
    print(a['name'])
    print(a[124])

输出

name
124

实例对象的key不管是否存在都会调用类中的__getitem__()方法。而且返回值就是__getitem__()方法中规定的return值。也就是说如果getitem里的方法写的不好就没有了意义了。
我们修改下代码,改变getitem的return的值

class A():
    def __init__(self,name=None,id=1):
        self.id=id
        self.name=name
    def __repr__(self):
        return "进入函数"
    def __getitem__(self, item):
       return self.__dict__[item] if __name__ == '__main__':
    a=A('lisa','123')
    print(a['name'])
    print(a[123])

输出

lisa
keyerror:123

输出了lisa和一个异常,改后的getitem做了什么事呢,
self.__dict__,是获取当前实例的所有属性的字典格式,后面的[item]就是取其对于的键值,这里我传了个name,实际就是取name属性的值也就是lisa。
对于123因为不存在这个属性所有报错了。这也是字典内部实现的一部分。

再来看一个例子,代码里已经加入了注释:

import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])

# 具名元组动态创建一个类Card,并含有两个属性rank和suit
# 用以构建只有少数属性但是没有方法的对象 class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')  # 扑克牌2到A组成的列表
    suits = 'spades diamonds clubs hearts'.split()  # 四种花色     def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]  # 笛卡尔积,13*4=52(除去两个王)     def __len__(self):
        return len(self._cards)     def __getitem__(self, position):
        # 调用f[0]时会进入
        return self._cards[position] if __name__ == '__main__':
    f = FrenchDeck()     print(f[0])
    # 在这里f[0]实际是f.__getitem__(0)

输出

Card(rank='2', suit='spades')

我们发现这个例子中还有一个__len__,那这个方法是干嘛的呢,我们继续往下看

__len__

在上面的例子中我们使用该方法,这个方法会在什么情况下发生呢,一个小例子来说明。

class B():

    def __init__(self):
        self.a_list = range(10)     def __len__(self):
        return len(self.a_list) if __name__ == '__main__':
     b = B()
     print(len(b))
     #在这里等价于
     #print(b.__len__())

输出

10

我们在调用len方法的时候会调用__len__。

__setitem__

__setitem__(self,key,value):该方法应该按一定的方式存储和key相关的value。在设置类实例属性时自动调用的。

class B():

    def __init__(self):
        self.a_list = range(10)     def __setitem__(self, key, value):
        self.__dict__[key] = value def cfun(a, b, c):
    print("新加入函数c") if __name__ == '__main__':
    b = B()
    b['a_list'] = "123"  # 这个会调用B类的\__setitem_方法_
    B.__setitem__ = cfun  # 改变settime方式变为cfun这个函数
    b['a_list'] = "123"  # 这次实际会调用cfun函数
    print(b.a_list)

输出

新加入函数c
123

__delitem__

执行del函数的时候会调用,如果继承了 继承
abc.MutableSequence的类就必须实现 __delitem__ 方法,这是 MutableSequence 类的一个抽象方法。

__eq__

a == b等同于a.__eq__(b)。
你可以在自己的类中定义 __eq__ 方法,决定 == 如何比较
实例。如果不覆盖 __eq__ 方法,那么从 object 继承的方法比较

python进阶之魔法函数的更多相关文章

  1. python 常用的魔法函数

    简介 在实际项目中,我们其实并不会太多的使用魔法函数,但是一些方法或者函数均是有魔法函数演变而来的,且在一些面试过程中会遇到一些关于常见方法的实现,就会牵扯到相应的魔法函数,此处将介绍一些我认为比较常 ...

  2. python 类的魔法函数 内置函数 类方法 静态方法 抽象类

    魔法函数 __init__函数 init函数会在实例化A这个类的时候被调用 class A(): def __init__(self): print('__init__函数') a = A() 显示结 ...

  3. Python 进阶 之 enumerate()函数

    enumerate()是Python的内置函数,无需依赖包,enumerate()作用是可以将生成器包装成生成器,类似于range,但enumerate()可以自动生成索引. enumerate(pa ...

  4. python进阶之内置函数和语法糖触发魔法方法

    前言 前面已经总结了关键字.运算符与魔法方法的对应关系,下面总结python内置函数对应的魔法方法. 魔法方法 数学计算 abs(args):返回绝对值,调用__abs__; round(args): ...

  5. Python进阶之返回函数

    返回函数 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB"," ...

  6. Python进阶-VI 生成器函数进阶、生成器表达式、推导式

    一.生成器函数进阶 需求:求取移动平均数 1.应用场景之一,在奥运会气枪射击比赛中,每打完一发都会显示平均环数! def show_avg(): print('你已进入显示移动平均环数系统!') a ...

  7. Python进阶-I 初识函数(function)

    函数 在java中叫方法. 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print() ...

  8. Python进阶之匿名函数(关键词lambda)

    匿名函数 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB"," ...

  9. Python进阶1---高阶函数、柯里化

    高阶函数 不相等  自定义sort函数 内建函数--高阶函数 #sort函数 def sort2(lst,key = None,reverse = False): res = [] if key is ...

随机推荐

  1. [福大软工] Z班 团队作业——UML设计 作业成绩

    团队作业--UML设计 作业链接 http://www.cnblogs.com/easteast/p/7745703.html 作业要求 1)团队分工(5分) 描述团队的每个成员分别完成了UML图的哪 ...

  2. Redis分布式锁的实现

    前段时间,我在的项目组准备做一个类似美团外卖的拼手气红包[第X个领取的人红包最大],基本功能实现后,就要考虑这一操作在短时间内多个用户争抢同一资源的并发问题了,类似于很多应用如淘宝.京东的秒杀活动场景 ...

  3. 基于接口回调详解JUC中Callable和FutureTask实现原理

    Callable接口和FutureTask实现类,是JUC(Java Util Concurrent)包中很重要的两个技术实现,它们使获取多线程运行结果成为可能.它们底层的实现,就是基于接口回调技术. ...

  4. Spring之事务操作(配置文件)

    UserDao.java package helloworld.tx; import org.springframework.jdbc.core.JdbcTemplate; public class ...

  5. 拿到一个崭新的Linux!

    买了服务器,这次买了半年,不能浪费了! 0.准备工作: l查看Ip:ifconfig  ip addr 不能上网? 执行以下: vi /etc/sysconfig/network-scripts/if ...

  6. MT【109】线面角最大时为二面角平面角

    解答:如图设C到$\alpha$面的距离为$d_1,C_1$到虚线距离为$d_2$ 所求距离$d=d_1+d_2=|AC|sin\theta+|CC_1|cos\theta=4\sqrt{2}sin\ ...

  7. 洛谷 P1437 [HNOI2004]敲砖块 解题报告

    P1437 [HNOI2004]敲砖块 题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下所示. 1 ...

  8. CF1096D Easy Problem(DP)

    貌似最近刷了好多的CF题…… 题目链接:CF原网 洛谷 题目大意:有一个长度为 $n$ 的字符串 $s$,删除第 $i$ 个字符需要代价 $a_i$.问使得 $s$ 不含有子序列(不是子串)" ...

  9. jQuery获取radio选中后的文字

    原文链接:http://blog.csdn.net/zhanyouwen/article/details/51393216 jQuery获取radio选中后的文字转载 2016年05月13日 10:3 ...

  10. python学习(28) 浅谈可变对象的单例模式设计

    python开发,有时候需要设计单例模式保证操作的唯一性和安全性.理论上python语言底层实现和C/C++不同,python采取的是引用模式,当一个对象是可变对象,对其修改不会更改引用的指向,当一个 ...