Python魔术方法专题


Posted in Python onJune 19, 2020

_del_

类的析构方法,它在对象被回收时执行,主要的作用时用来释放资源(内存 文件 进程等)

因为Python内存回收机制,使得Python的del方法的执行时间是不确定的,因此不推荐在Python中使用析构方法。

class Bar(object):
  def __del__(self):
    print("被回收了! ~")


a = Bar()

a.__del__() # 主动调用是没用的,因为引用计数不为零,并不会回收资源 gc
print("已经删除a了")
print(a)

del a
# print(a)

_dict_

  • 是一个绑定对象属性的字典 存储的是属性的 键值对应关系
  • 可以直接通过修改这个字典来为对象添加属性(但是不推荐这样做!会使得程序的可读性降低 破坏程序的结构 充分理解 后使用 但是也要慎重)甚至 你可以通过修改 dict 来为对象添加方法 例如 func

_slots_

  • 限定类的对象只能拥有某些属性,防止写错属性名,也可以实现不允许动态添加其他属性。
  • 形式:一个元组或 列表
  • 需要注意 一旦类指定了 slots 那就意味着 类的属性键值绑定关系 由__slots__来维护 也就是说 对象将没有 __dict__方法
  • __slots__只能约束本类,不能约束继承它的子类,如果子类也定义了slots 方法,那么对子类的约束将会成为两者的并集。
class Bar(object):
  __slots__ = ('name', 'gender')

  def __init__(self, name='monkey'):
    self.name = name
    self.gender = 'male'


a = Bar()
a.age = 18  # 动态添加属性是会报错的。
print(a.name)

_str_

必须返回一个str 类型 在打印对象的时候将会 打印返回的 str 而不是默认的 self.str
:return: <main.... object at 0x1084b7208>

class Bar(object):

  def __str__(self):
    return "Bar"


a = Bar()
print(a) # Bar

_repr_

将对象转化成对解释器友好的形式,它跟eval()方法联系紧密,通常repr()调用 对象的__repr__方法,该方法返回以字符串格式的 对解释器友好的 对象描述,eval() 可以将repr()的返回值 转化为原对象。

这玩意很强大,它是最直接的多态体现,几乎任何类对象都实现了它,但是每个返回的结果都是不一样的。

_class_

_class_ 允许通过对象调用类的方法和操作类的属性即 object.__class__ 可以拿到这个对象的类
拿到类后可以进行新的实例化 操作类的属性 调用类的方法等.

class Bar(object):
  name = 'monkey'


a = Bar()
print(a.__class__.name)  # 允许通过实例化对象访问类

_doc_

打印对象或类或方法的文档字符串

class Bar(object):
  """
  A simple show class!
  """
  name = 'monkey'

  def get_name(self):
    """
    get class argument name
    """
    return self.__class__.name


a = Bar()
print(a.__class__.__doc__)
print(a.__class__.get_name.__doc__)

#  A simple show class!
#  
#
#    get class argument name

_base_

用来返回类的父类

_bases_

用来返回类的继承列表

class Lady(object):
  """ """

class Small(object):
  """ """

class SmallLady(Small, Lady):
  """"""


print(Lady.__base__)  # <class 'object'>
print(SmallLady.__bases__)  # (<class '__main__.Small'>, <class '__main__.Lady'>)

_iter_

必须返回可迭代对象

这个对象需要实现__next__方法。

_next_

每次返回迭代器的下一个值或一个迭代异常来终止迭代。

_len_

每次返回迭代器的下一个值或一个迭代异常来终止迭代。

class ListMeta(type):
  def __call__(self, data, *args, **kwargs):  # 使得self 也就是实例化出的类 是可调用的 List() 这里的self指的是 将要 实例化出来的类 本身
    self.__init__(self,data)
    return self

  def __str__(self):
    result = self.clean_data(self) # 是 List 可以返回期望的列表格式 将对象转化为对人友好的字符串
    result = '[{}]'.format(result[:-1])
    return result

  def __repr__(self):
    return 'List({})'.format(self.__str__())  # 转化为对解释器友好的字符串

  def __iter__(self):		# 返回实现了迭代器协议的对象
    return self # 它本身实现了 __next__

  def __next__(self):		# 实现迭代器协议,每次返回下一个值 或 一个迭代异常终止迭代
    if self.index >= len(self.data):  
      raise StopIteration
    else:
      value = self.data[self.index]
      self.index += 1
      return value

  def __len__(self):  # 返回对象的长度,len()函数会执行对象的 __len__方法
    return self.len


class List(metaclass=ListMeta):

  def __init__(self, data):
    self.data = data
    self.index = 0
    self.len = len(self.data)
    

l = List([1,2,3,4,5,6,7])

print(l)
print(len(l))

for i in l:
  print(i)

_hash_

必须返回一个int类型的数据,并且可以唯一的表示这个对象。这点很重要。

_getattribute_

  • 此方法在每次访问对象的属性之前都会被调用,它容易使你陷入无限的递归中。
  • 如果需要对对象属性的访问做一些限制 譬如 以"block_" 开头的属性不允许访问可以这样来实现,这时候她是非常有用的。
  • 如果该方法找到了对象的属性,那么直接返回其属性值,如果找不到或报错了,无论如何没有达到预期的结果,那就调用 _getattr_ 方法。

_getattr_

  • 当以 点 属性名的形式访问属性时,如果属性不存在,则会执行对象的 _getattr_ 方法 该方法接受一个变量,item,即访问的属性名。返回值为本次获取的属性值,但是这个值并没有写入 对象的属性字典里。
  • 也就是说如果属性在__getattribute__中找到是不会执行这个方法的。
  • 这个方法也容易陷入无限的递归当中。

_setattr_

以点属性名的形式设置属性时,会调用 _setattr_ 方法,此方法需要将属性名和属性值的对应关系写入关系字典__dict__里。如果重写了该方法,一定不要忘记手动的更新 对象属性字典。

class Storage(object):

  def __init__(self, name):
    self.name = name  # 调用__setattr__方法

  def __getattribute__(self, item):  # 每个属性访问前都先调用该方法
    print('getattribute: %s' % item)
    ret = True
    if item == 'error':
      raise AttributeError(r'Error ~ "error"')  # 报错了依然执行~ 
    else:
      ret = object.__getattribute__(self, item)
    return ret

  def __getattr__(self, item):
    print('getattr: %s' % item)
    try:
      return self.__dict__[item]
    except (IndexError, KeyError)as e:
      print('No attribute %s ' % e)
    return '%s is error' % item

  def __setattr__(self, key, value):
    print('setattr: %s ' % key)
    self.__dict__.update({key:value})


file = Storage('file')
name = file.error  # 调用 __getattr__ 方法
# setattr: name 
# getattribute: __dict__
# getattribute: error
# getattr: error
# getattribute: __dict__
# No attribute 'error'

以上就是Python魔术方法专题的详细内容,更多关于Python 魔术方法的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
使用python删除nginx缓存文件示例(python文件操作)
Mar 26 Python
Python中让MySQL查询结果返回字典类型的方法
Aug 22 Python
Python实现的tab文件操作类分享
Nov 20 Python
python获得文件创建时间和修改时间的方法
Jun 30 Python
Python实现的redis分布式锁功能示例
May 29 Python
推荐10款最受Python开发者欢迎的Python IDE
Sep 16 Python
python高效过滤出文件夹下指定文件名结尾的文件实例
Oct 21 Python
python实现名片管理系统项目
Apr 26 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
Dec 26 Python
宝塔面板成功部署Django项目流程(图文)
Jun 22 Python
PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?
Aug 17 Python
Python必备技巧之函数的使用详解
Apr 04 Python
关于Theano和Tensorflow多GPU使用问题
Jun 19 #Python
如何对python的字典进行排序
Jun 19 #Python
浅谈Python中的继承
Jun 19 #Python
python程序需要编译吗
Jun 19 #Python
python中round函数如何使用
Jun 19 #Python
keras实现theano和tensorflow训练的模型相互转换
Jun 19 #Python
Keras 切换后端方式(Theano和TensorFlow)
Jun 19 #Python
You might like
php生成文件
2007/01/15 PHP
php采用curl模仿登录人人网发布动态的方法
2014/11/07 PHP
php使用Session和文件统计在线人数
2015/07/04 PHP
PHP magento后台无法登录问题解决方法
2016/11/24 PHP
常用简易JavaScript函数
2009/04/09 Javascript
javascript操作cookie_获取与修改代码
2009/05/21 Javascript
javaScript parseInt字符转化为数字函数使用小结
2009/11/05 Javascript
多浏览器兼容性比较好的复制到剪贴板的js代码
2011/10/09 Javascript
Javascript 面向对象(二)封装代码
2012/05/23 Javascript
JavaScript弹出对话框的三种方式
2016/03/23 Javascript
javascript拖拽效果延伸学习
2016/04/04 Javascript
移动端界面的适配
2017/01/11 Javascript
整理关于Bootstrap警示框的慕课笔记
2017/03/29 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
2017/04/25 Javascript
vue动态添加路由addRoutes之不能将动态路由存入缓存的解决
2019/02/19 Javascript
jQuery-Citys省市区三级菜单联动插件使用详解
2019/07/26 jQuery
js实现限定区域范围拖拉拽效果
2020/11/20 Javascript
Python中的特殊语法:filter、map、reduce、lambda介绍
2015/04/14 Python
python爬取哈尔滨天气信息
2018/07/14 Python
基于Django ORM、一对一、一对多、多对多的全面讲解
2019/07/26 Python
代码总结Python2 和 Python3 字符串的区别
2020/01/28 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
浅谈django channels 路由误导
2020/05/28 Python
在tensorflow下利用plt画论文中loss,acc等曲线图实例
2020/06/15 Python
Python爬虫之Selenium下拉框处理的实现
2020/12/04 Python
CSS3制作hover下划线动画
2017/03/27 HTML / CSS
波兰最大的儿童服装连锁店之一:5.10.15.
2018/02/11 全球购物
Myprotein俄罗斯官网:欧洲第一运动营养品牌
2019/05/05 全球购物
介绍一下JMS编程步骤
2015/09/22 面试题
教师专业理论水平的自我评价分享
2013/11/09 职场文书
绩效工资实施方案
2014/03/15 职场文书
教师党员公开承诺书
2014/03/25 职场文书
咖啡店创业计划书
2014/08/15 职场文书
群众路线调研报告范文
2014/11/03 职场文书
员工手册董事长致辞
2015/07/29 职场文书
业余无线电通联Q语
2022/02/18 无线电