python魔法方法-属性转换和类的表示详解


Posted in Python onJuly 22, 2016

类型转换魔法

类型转换魔法其实就是实现了str、int等工厂函数的结果,通常这些函数还有类型转换的功能,下面是一些相关的魔法方法:

•__int__(self)

•转换成整型,对应int函数。

•__long__(self)

•转换成长整型,对应long函数。

•__float__(self)

•转换成浮点型,对应float函数。

•__complex__(self)

•转换成 复数型,对应complex函数。

•__oct__(self)

•转换成八进制,对应oct函数。

•__hex__(self)

•转换成十六进制,对应hex函数。

•__index__(self)

•首先,这个方法应该返回一个整数,可以是int或者long。这个方法在两个地方有效,首先是 operator 模块中的index函数得到的值就是这个方法的返回值,其次是用于切片操作,下面会专门进行代码演示。

•__trunc__(self)

•当 math.trunc(self) 使用时被调用.__trunc__返回自身类型的整型截取 (通常是一个长整型).

•__coerce__(self, other)

•实现了类型的强制转换,这个方法对应于 coerce 内建函数的结果(python3.0开始去掉了此函数,也就是该魔法方法也没意义了,至于后续的版本是否重新加入支持,要视官方而定。)

•这个函数的作用是强制性地将两个不同的数字类型转换成为同一个类型,例如:

python魔法方法-属性转换和类的表示详解

方法返回一个元祖,分别对应转换后的两个数字。其优先级为:复数>浮点数>长整型>整型。在转换的时候,会转换为两个参数中优先级高的类型。当转换无法完成的时候,会触发 TypeError。

而当我们定义这个魔法方法时,如果转换无法完成,应该返回None。

这里有个重要的机制,当python进行运算的时候,如 1 + 1.0 时,会先调用 coerce 函数将其转换为同一个类型,然后再进行运行,这也就是为什么 1 + 1.0 = 2.0,因为转换之后实际进行的运算为 1.0 +1.0。得到这样的结果也就不奇怪了。

代码示例:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __int__(self):
    return int(self.x) + 1

  def __long__(self):
    return long(self.x) + 1

a = Foo(123)
print int(a)
print long(a)
print type(int(a))
print type(long(a))

python魔法方法-属性转换和类的表示详解

这里要注意一点,魔法方法的返回值必须符合预期,例如 __int__ 就应该返回一个 int 类型,如果我们任性地返回其他类型,例如字符串(str)、列表(list)等,会报错。

def __int__(self):
    return str(self.x)

python魔法方法-属性转换和类的表示详解

def __int__(self):
    return list(self.x)

python魔法方法-属性转换和类的表示详解

但是 int 可以返回 long,而 long 返回 int 时会自动被处理成 long:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __int__(self):
    return long(self.x) + 1

  def __long__(self):
    return int(self.x) + 1

a = Foo(123)
print int(a)
print long(a)
print type(int(a))
print type(long(a))

python魔法方法-属性转换和类的表示详解

以上发生在python2.7.11上,这是一个很奇怪的行为,以至于我认为其可能是一个 BUG,总之我们在使用的时候要注意要返回对应的类型就是了,以免出错。

__index__(self):

首先是对应于operator.index(),operator.index(a)就相当于a.__index__():

import operator

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __index__(self):
    return self.x + 1

a = Foo(10)
print operator.index(a)

python魔法方法-属性转换和类的表示详解

另一个是很神奇的特效,当其用于序列中时:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __index__(self):
    return 3

a = Foo('scolia')
b = [1, 2, 3, 4, 5]
print b[a]
print b[3]

python魔法方法-属性转换和类的表示详解

可以作为索引一样使用,可进行切片操作:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __index__(self):
    return int(self.x)

a = Foo('1')
b = Foo('3')
c = [1, 2, 3, 4, 5]
print c[a:b]

 python魔法方法-属性转换和类的表示详解

其实切片内部使用的函数 slice 对其进行了处理,有兴趣的同学可以去了解这个函数:

a = Foo('1')
b = Foo('3')
c = slice(a, b)
print c
d = [1, 2, 3, 4, 5]
print d[c]

 __coerce__(self, other):

代码示例:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __coerce__(self, other):
    return self.x, str(other.x)

class Boo(object):
  def __init__(self, x):
    self.x = x

  def __coerce__(self, other):
    return self.x, int(other.x)

a = Foo('123')
b = Boo(123)
print coerce(a, b)
print coerce(b, a)

python魔法方法-属性转换和类的表示详解

 总结:是调用了第一个参数的魔法方法。

类的表示 :

类的表示其实就是对外的特征,例如使用print语句时,打印出来的是什么,其实本质上也是对应函数的输出:

•__str__(self)

•定义当 str() 被你的一个类的实例调用时所要产生的行为。因为print默认调用的就是str()函数。

•__repr__(self)

•定义当 repr()  被你的一个类的实例调用时所要产生的行为。 str() 和 repr() 的主要区别是其目标群体。 repr() 返回的是机器可读的输出,而 str() 返回的是人类可读的。  repr() 函数是交换模式默认调用的

•函数。

•__unicode__(self)

•定义当 unicode() 被你的一个类的实例调用时所要产生的行为。 unicode() 和 str() 很相似,但是返回的是unicode字符串。注意,如果对你的类调用 str() 然而你只定义了 __unicode__() ,那么其将不会

•工作。你应该定义 __str__() 来确保调用时能返回正确的值,并不是每个人都有心情去使用unicode()。

•__format__(self, formatstr)

•定义当你的一个类的实例被用来用新式的格式化字符串方法进行格式化时所要产生的行为。例如, "Hello, {0:abc}!".format(a) 将会导致调用 a.__format__("abc") 。这对定义你自己的数值或字符串类型

•是十分有意义的,你可能会给出一些特殊的格式化选项。

•__hash__(self)

•定义当 hash()被你的一个类的实例调用时所要产生的行为。它必须返回一个整数,用来在字典中进行快速比较。

•请注意,实现__hash__时通常也要实现__eq__。有下面这样的规则:a == b 暗示着 hash(a) == hash(b) 。也就是说两个魔法方法的返回值最好一致。

•这里引入一个‘可哈希对象'的概念,首先一个可哈希对象的哈希值在其生命周期内应该是不变的,而要得到哈希值就意味要实现__hash__方法。而哈希对象之间是可以比较的,这意味着要实现__eq__或

•者__cmp__方法,而哈希对象相等必须其哈希值相等,要实现这个特性就意味着__eq__的返回值必须和__hash__一样。

•可哈希对象可以作为字典的键和集合的成员,因为这些数据结构内部使用的就是哈希值。python中所有内置的不变的对象都是可哈希的,例如元组、字符串、数字等;而可变对象则不能哈希,例如列表、

•字典等。

•用户定义的类的实例默认是可哈希的,且除了它们本身以外谁也不相等,因为其哈希值来自于 id 函数。但这并不代表 hash(a) == id(a),要注意这个特性。

•__nonzero__(self)

•定义当 bool() 被你的一个类的实例调用时所要产生的行为。本方法应该返回True或者False,取决于你想让它返回的值。(python3.x中改为__bool__)

•__dir__(self)

•定义当 dir() 被你的一个类的实例调用时所要产生的行为。该方法应该返回一个属性的列表给用户。

•__sizeof__(self)

•定义当 sys.getsizeof() 被你的一个类的实例调用时所要产生的行为。该方法应该以字节为单位,返回你的对象的大小。这通常对于以C扩展的形式实现的Python类更加有意义,其有助于理解这些扩展。

这里并没有什么特别难以理解的地方,所以代码例子就略去了。

以上这篇python魔法方法-属性转换和类的表示详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
py2exe 编译ico图标的代码
Mar 08 Python
python获取指定网页上所有超链接的方法
Apr 04 Python
深入理解Django中内置的用户认证
Oct 06 Python
Python+OpenCV目标跟踪实现基本的运动检测
Jul 10 Python
Python拆分大型CSV文件代码实例
Oct 07 Python
Python django搭建layui提交表单,表格,图标的实例
Nov 18 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
python shapely.geometry.polygon任意两个四边形的IOU计算实例
Apr 12 Python
Python爬取12306车次信息代码详解
Aug 12 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
Oct 15 Python
Python+Appium实现自动化清理微信僵尸好友的方法
Feb 04 Python
Anaconda安装pytorch及配置PyCharm 2021环境
Jun 04 Python
wxpython中自定义事件的实现与使用方法分析
Jul 21 #Python
wxpython中Textctrl回车事件无效的解决方法
Jul 21 #Python
Python实现Sqlite将字段当做索引进行查询的方法
Jul 21 #Python
python装饰器初探(推荐)
Jul 21 #Python
python魔法方法-自定义序列详解
Jul 21 #Python
浅谈Python 字符串格式化输出(format/printf)
Jul 21 #Python
分享python数据统计的一些小技巧
Jul 21 #Python
You might like
PHP开发过程中常用函数收藏
2009/12/14 PHP
PHP版国家代码、缩写查询函数代码
2011/08/14 PHP
php+js实现图片的上传、裁剪、预览、提交示例
2013/08/27 PHP
PHP中对缓冲区的控制实现代码
2013/09/29 PHP
jquery ready函数源代码研究
2009/12/06 Javascript
JavaScript 异步方法队列链实现代码分析
2010/06/05 Javascript
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
2011/05/07 Javascript
JQuery遍历json数组的3种方法
2014/11/08 Javascript
JavaScript中实现单体模式分享
2015/01/29 Javascript
JavaScript控制listbox列表框的项目上下移动的方法
2015/03/18 Javascript
js获取form的方法
2015/05/06 Javascript
js判断PC端与移动端跳转
2020/12/24 Javascript
如何使用Bootstrap 按钮实例详解
2017/03/29 Javascript
JS解决移动web开发手机输入框弹出的问题
2017/03/31 Javascript
vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据
2017/04/22 Javascript
JavaScript学习笔记之函数记忆
2017/09/06 Javascript
在vue项目创建的后初始化首次使用stylus安装方法分享
2018/01/25 Javascript
ES6知识点整理之对象解构赋值应用示例
2019/04/17 Javascript
JavaScript跳出循环的三种方法(break, return, continue)
2019/07/30 Javascript
JQuery常用选择器功能与用法实例分析
2019/12/23 jQuery
webpack 最佳配置指北(推荐)
2020/01/07 Javascript
vue npm install 安装某个指定的版本操作
2020/08/11 Javascript
python使用正则表达式替换匹配成功的组并输出替换的次数
2017/11/22 Python
PyQt5每天必学之工具提示功能
2018/04/19 Python
Python中Subprocess的不同函数解析
2019/12/10 Python
哈工大自然语言处理工具箱之ltp在windows10下的安装使用教程
2020/05/07 Python
解决django框架model中外键不落实到数据库问题
2020/05/20 Python
pycharm进入时每次都是insert模式的解决方式
2021/02/05 Python
2014年教师节演讲稿
2014/09/03 职场文书
解除同居协议书
2015/01/29 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
财务经理岗位职责范本
2015/04/08 职场文书
企业财务管理制度范本
2015/08/04 职场文书
超市员工管理制度
2015/08/06 职场文书
2016年母亲节广告语
2016/01/28 职场文书
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏