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 相关文章推荐
Python continue语句用法实例
Mar 11 Python
Python最基本的输入输出详解
Apr 25 Python
Windows下搭建python开发环境详细步骤
Jul 20 Python
shelve  用来持久化任意的Python对象实例代码
Oct 12 Python
python实现微信自动回复功能
Apr 11 Python
Python学习笔记之自定义函数用法详解
Jun 08 Python
python elasticsearch环境搭建详解
Sep 02 Python
Pytorch中accuracy和loss的计算知识点总结
Sep 10 Python
Pytorch之卷积层的使用详解
Dec 31 Python
django 读取图片到页面实例
Mar 27 Python
tensorflow+k-means聚类简单实现猫狗图像分类的方法
Apr 28 Python
Pytest中skip skipif跳过用例详解
Jun 30 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世纪万年历
2006/12/06 PHP
检测png图片是否完整的php代码
2010/09/06 PHP
PHP递归调用的小技巧讲解
2013/02/19 PHP
PHP框架性能测试报告
2016/05/08 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
用于自动添加Digg This!按钮的JavaScript
2006/12/23 Javascript
用js实现计算加载页面所用的时间
2010/04/02 Javascript
网页上的Javascript编辑器和代码格式化
2010/04/25 Javascript
JavaScript自定义事件介绍
2013/08/29 Javascript
js中substring和substr的详细介绍与用法
2013/08/29 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
2014/09/03 Javascript
原生javascript实现图片滚动、延时加载功能
2015/01/12 Javascript
jQuery+CSS实现滑动的标签分栏切换效果
2015/12/17 Javascript
javascript创建含数字字母的随机字符串方法总结
2016/08/01 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
2016/12/22 Javascript
关于vue面试题汇总
2018/03/20 Javascript
Angular-UI Bootstrap组件实现警报功能
2018/07/16 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
pm2发布node配置文件ecosystem.json详解
2019/05/15 Javascript
react中Suspense的使用详解
2019/09/01 Javascript
Vue Router 实现动态路由和常见问题及解决方法
2020/03/06 Javascript
javascript的hashCode函数实现代码小结
2020/08/11 Javascript
[06:53]2018DOTA2国际邀请赛寻真——勇于创新的Vici Gaming
2018/08/14 DOTA
Python中处理字符串之islower()方法的使用简介
2015/05/19 Python
Python 读取指定文件夹下的所有图像方法
2018/04/27 Python
Centos下实现安装Python3.6和Python2共存
2018/08/15 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
2018/12/18 Python
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
实例讲解Python中整数的最大值输出
2019/03/17 Python
Python unittest单元测试框架实现参数化
2020/04/29 Python
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
HTML5 canvas基本绘图之填充样式实现
2016/06/27 HTML / CSS
Parfume Klik丹麦:香水网上商店
2018/07/10 全球购物
Juice Beauty官网:有机美容产品,护肤与化妆品
2020/06/13 全球购物
党的群众路线教育实践活动个人对照检查剖析材料
2014/09/23 职场文书
导游词之云南省玉龙雪山
2019/12/19 职场文书