__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. Central Control Over Distributed Routing阅读笔记

    Central Control Over Distributed Routing 0.ABSTRACT1.Introduction2.Flexible Fibbing3.Augmenting Topo ...

  2. DHCP分配固定IP

    https://www.cnblogs.com/liu1026/p/9829337.html 按照上面的操作实验好后在DHCP服务端的配置文件中加入

  3. beta NO1

    031602111 傅海涛 1.今天进展 笔记颜色统一,解决笔记的同步性和完整性 2.存在问题 office文档转换的时间问题 3.明天安排 增加新功能和完善之前的功能 4.心得体会 接口真难 031 ...

  4. beta 圆桌 3

    2018-12-16图片缺失,当日数据: 总工作量:24 已完成:5 剩余:19 031602111 傅海涛 1.今天进展 实时字幕的实现大概 2.存在问题 实时字幕存在不稳定和耗费资源 3.明天安排 ...

  5. TCP/IP 之 大明王朝邮差 (转)

    原创: 刘欣 码农翻身 2016-05-12 前言: 本文主要想说一下TCP的知识, 比喻有不恰当之处,敬请包涵. 大明王朝天启四年, 清晨. 天色刚蒙蒙亮,我就赶着装满货物的马车来到了南城门, 这里 ...

  6. Oracle client 使用 .net程序连接 数据库时 出现 8.1.7 的解决办法

    1. GS产品 连接oracle数据库时出现错误图示 2. 其实解决这个问题的办法很简单 一般是 修改一下 Oracle的app 目录的权限 最简单的办法是增加 everyone 权限 然后重启机器即 ...

  7. 数据库中增加操作insert into的用法和查询select的用法

    insert into的用法 1.一条insert into 可以插入多条记录 2.insert into 能判断主键是否冲突,和做出冲突处理 如果主键冲突的话会报错,还能写成如果冲突就更新的形式格式 ...

  8. 用Setup Factory7.0怎样打包delphi的BDE?

    BDE打包发布实例操作步骤如下: 使用软件:Setup Factory 7.0打包 把C:\Program Files\Common Files\Borland Shared中的所有文件和你的开发的应 ...

  9. Hbase之IP变更后无法启动问题解决

    # 修改hbase IP配置文件地址:/opt/hbase-1.1.13/conf/hbase-site.xml <property> <name>hbase.zookeepe ...

  10. debian开启cgroup memory子系统

    Debian系统默认是关闭cgroup memory子系统的. 1.修改grub启动参数 # vim /etc/default/grub GRUB_CMDLINE_LINUX="cgroup ...