文章目录

  • 一、`__getitem__` 获取属性
  • 二、`__setitem__` 设置属性
  • 三、`__delitem__` 删除属性
  • 四、`__len__` 求长度
  • 五、`__call__` 将类变成一个可调用的函数

python 中以 “__” 开头和结尾的成员,都被称为类的特殊成员(特殊属性和方法)。

一、__getitem__ 获取属性

在字典和列表中,我们经常会用到 [] 来获取对应元素,因为字典和列表中都内置了 __getitem__ 方法。

"__getitem__" in (dir(list))
>>>
True
"__getitem__" in (dir(dict))
>>>
True

__getitem__ 的作用:

当定义了一个类的时候,当该类的实例化对象通过 [] 来取值的时候,会调用 __getitem__ 方法,也就是说这个方法能够返回与指定键相关联的值

使用 [] 对对象中的属性进行取值、赋值或删除时,会自动触发对应的 __getitem____setitem____delitem__ 方法

class DataBase:def __init__(self,id,address):#初始化方法self.id=idself.address=addressself.d={self.id:1,self.address:"192.168.1.1"}def __getitem__(self,key):return self.d.get(key,"default")data=DataBase(1,"192.168.1.1")
print(data['hi'])         # output default
print(data[data.id])      # output 1
print(data[data.address]) # output 192.168.1.1
print(data[1])            # output 1
class Person(object):def __init__(self, info):self.info = infodef __getitem__(self, key):print('__getitem__:', key)return self.info[key]
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
print(person['xiaoming'])
>>>
__getitem__: xiaoming
2

如果没有定义 __getitem__ 但使用 [] 来取属性的话,则会报错:

class Person(object):def __init__(self, info):self.info = info
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
print(person['xiaoming'])
>>>
TypeError: 'Person' object is not subscriptable

二、__setitem__ 设置属性

__setitem__ 可以设置属性,可以新增,也可以修改现有的

class Person(object):def __init__(self, info):self.info = infodef __setitem__(self, key, value):print('__setitem__:', key, value)self.info[key] = value
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)###### 2、修改
person['xiaobai'] = 4
print('person_info after change:', person_info)
>>>
__setitem__: xiaobai 4
person_info after change: {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3, 'xiaobai': 4}
class Person(object):def __init__(self, info):self.info = infodef __setitem__(self, key, value):print('__setitem__:', key, value)self.info[key] = value
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)###### 2、修改
person['xiaowang'] = 5
print('person_info after change:', person_info)
>>>
__setitem__: xiaowang 5
person_info after change: {'xiaowang': 5, 'xiaoming': 2, 'xiaohong': 3}

三、__delitem__ 删除属性

class Person(object):def __init__(self, info):self.info = infodef __delitem__(self, key):print('__delitem__:', key)del self.info[key]def __len__(self):return len(self.info)
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
###### 3、删除
del person['xiaoming']
print('person_info after del:', person_info)
>>>
__delitem__: xiaoming
person_info after del: {'xiaowang': 1, 'xiaohong': 3}

四、__len__ 求长度

class Person(object):def __init__(self, info):self.info = infodef __len__(self):return len(self.info)
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
###### 4、求长度
print('final len of info:', len(person_info))
>>>
final len of info: 3

总体代码:

class Person(object):def __init__(self, info):self.info = infodef __getitem__(self, key):print('__getitem__:', key)return self.info[key]def __setitem__(self, key, value):print('__setitem__:', key, value)self.info[key] = valuedef __delitem__(self, key):print('__delitem__:', key)del self.info[key]def __len__(self):return len(self.info)
person_info = {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3}
person = Person(person_info)
###### 1、获取
print('xiaoming:', person['xiaoming'])
>>>
__getitem__: xiaoming
xiaoming: 2###### 2、修改
person['xiaobai'] = 4
print('person_info after change:', person_info)
>>>
__setitem__: xiaobai 4
person_info after change: {'xiaowang': 1, 'xiaoming': 2, 'xiaohong': 3, 'xiaobai': 4}###### 3、删除
del person['xiaoming']
print('person_info after del:', person_info)
>>>
__delitem__: xiaoming
person_info after del: {'xiaowang': 1, 'xiaohong': 3, 'xiaobai': 4}###### 4、求长度
print('final len of info:', len(person_info))
>>>
final len of info: 3

五、__call__ 将类变成一个可调用的函数

__call__ 的本质其实是将一个类变成一个函数,使得这个类的实例可以像函数一样调用

python 中,凡是可以将 () 直接应用到自身并执行,都称为“可调用对象”,可调用对象包括自定义函数、python 内置函数、以及类实例对象(即有 call 的类)

对于可调用对象,名称() 可以理解为 名称.__call__() 的简写,

class Test(object):def __init__(self, name):self.name = namedef __call__(self):print('here is in __call__!')print('my name is {}'.format(self.name))
test = Test('xiaowang')
test()
>>>
here is in __call__!
my name is xiaowang

当类中没写 __call__ 的时候:

class Test(object):def __init__(self, name):self.name = name
test = Test('xiaowang')
test()
>>>
TypeError: 'Test' object is not callable
报错该对象无法调用

【python 10】python 魔术方法相关推荐

  1. python描述符魔术方法_Python类型转换的魔术方法详解

    本文讨论python中将某个复杂对象转换为简单对象或数据类型的常用魔术放啊,这些在编程中是十分有用的. 1.__str__方法. 在讲解本方法前我们先打开一个jupyter notebook,随意创建 ...

  2. python 中的魔术方法 getitem setitem

    python 中的魔术方法 getitem setitem https://docs.python.org/3/reference/datamodel.html?highlight=iter#obje ...

  3. Python中的魔术方法详解

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",中文称『魔术方法』,例如类的初始化方法 __init__ ,P ...

  4. python 类的魔术方法_python中类的魔术方法

    目的:学习python中class的magic methods,提高编程效率. 环境:ubuntu 16.4   python 3.5.2 在学习class时一定会接触到它的magic methods ...

  5. python 析构函数_常用的python类的魔术方法

    对于很少使用python编写大型代码的朋友可能会忘记python还是一种面向对象的语言.在其他面向对象的语言中有构造函数.析构函数等等在生命周期不同时机自动调用的函数,python当然也是有的.除此之 ...

  6. python中的魔术方法

    魔术方法 魔术方法就是一个类/对象中的方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法是在特定时刻自动触发. 1.__init__ 初始化魔术方法 触发时机:初始化对象时触发(不是实例化触发 ...

  7. Python笔记_20_魔术方法

    文章目录 魔术方法(特定时机自动触发) `__init__` (构造方法) `__new__`魔术方法 `__del__ `(析构方法) `__call__ ` 魔术方法 `__str__` 魔术方法 ...

  8. python描述符魔术方法_学习笔记-Python基础9-面向对象编程OOP-类的成员描述符(property)、类的常用内置属性、类的常用魔术方法、类和对象的三种方法...

    一.类的成员描述符(property) 类的成员描述符是为了在类中,对类的成员属性进行相关操作而创建的一种方式,大部分属于数据清洗 属性有三种操作:get获取属性值.set修改或添加属性.delete ...

  9. python所有的魔术方法钩子函数

    C.__init__(self[, arg1, ...]) 构造器(带一些可选的参数) C.__new__(self[, arg1, ...]) 构造器(带一些可选的参数)通常用在设置不变数据类型的子 ...

  10. Python 中的魔术方法(双下划线开头和结尾的方法)

    https://gitbook.cn/books/5ffd564919f81e0b10c9e39f/index.html https://www.cnblogs.com/pyxiaomangshe/p ...

最新文章

  1. 【Markdown】如何在微信公众号上写markdown的文章
  2. 转载 python扩展问题”unable to find vcvarsall.bat“的解决
  3. cdf2rdf--复对角矩阵转化为实对角矩阵
  4. linux的spio在服务器间,scp 将数据从一台linux服务器复制到另一台linux服务器
  5. [转]【高并发】高并发秒杀系统架构解密,不是所有的秒杀都是秒杀!
  6. 行为设计模式 - 模板方法设计模式
  7. Interlocked原子访问系列函数
  8. 【机器学习】从房价预测问题看回归算法
  9. 企业启动计划预算管理的原因解析
  10. 使用HTML+CSS设计个人简历
  11. jquery提交整个form表单
  12. python mssql get image bin_python实现mssql里点数据集到AutoCAD的文本转换
  13. 青果教务系统适配小爱课程表
  14. PHP 图片无损压缩
  15. 电脑管家软件搬家没有历史记录
  16. frame和bounds的区别
  17. vue音乐添加,控制开关
  18. 汇编综合实验--学生管理系统
  19. mysql数据库的在线数据备份与数据恢复
  20. android点击展开内容,Android编程实现Listview点击展开和隐藏的方法

热门文章

  1. Cisco 2811 IOS 升级实战
  2. (一)Builder(建造者)模式
  3. android一些小技巧
  4. 从Notes迁移到Exchange Server 2010 之三
  5. 努力,做个淡定的女子
  6. Shell 命令大全Xhell入门
  7. Java事务处理总结【JDBC事务|JTA事务|容器事务】
  8. Struts Gossip: 模組化程式
  9. ceph linux内核配置,centos 7.4-aarch64如何编译Ceph
  10. 添加vlan后无法上网_VLAN攻击如何有效防范?搞定虚拟局域网就在以下三点