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 相关文章推荐
wxpython 最小化到托盘与欢迎图片的实现方法
Jun 09 Python
浅谈Python中用datetime包进行对时间的一些操作
Jun 23 Python
Python实现在线音乐播放器
Mar 03 Python
Python连接phoenix的方法示例
Sep 29 Python
详解Python nose单元测试框架的安装与使用
Dec 20 Python
深入理解Python异常处理的哲学
Feb 01 Python
Python socket实现多对多全双工通信的方法
Feb 13 Python
python系列 文件操作的代码
Oct 06 Python
numpy中三维数组中加入元素后的位置详解
Nov 28 Python
python利用递归方法实现求集合的幂集
Sep 07 Python
python3实现常见的排序算法(示例代码)
Jul 04 Python
详解Python内置模块Collections
Mar 22 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
咖啡的种类和口感
2021/03/03 新手入门
php MYSQL 数据备份类
2009/06/19 PHP
PHP获取163、gmail、126等邮箱联系人地址【已测试2009.10.10】
2009/10/11 PHP
基于PHP输出缓存(output_buffering)的深入理解
2013/06/13 PHP
PHP浮点比较大小的方法
2016/02/14 PHP
ucenter中词语过滤原理分析
2016/07/13 PHP
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
2016/12/20 Javascript
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
Angular4 组件通讯方法大全(推荐)
2018/07/12 Javascript
JavaScript引用类型RegExp基本用法详解
2018/08/09 Javascript
微信小程序+云开发实现欢迎登录注册
2019/05/24 Javascript
微信公众号开发之微信支付代码记录的实现
2019/10/16 Javascript
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
在博客园博文中添加自定义右键菜单的方法详解
2020/02/05 Javascript
node+vue实现文件上传功能
2020/05/28 Javascript
vue实现购物车的小练习
2020/12/21 Vue.js
手写Vue源码之数据劫持示例详解
2021/01/04 Vue.js
[02:41]2015国际邀请赛中国区预选赛观战指南
2015/05/20 DOTA
分享15个最受欢迎的Python开源框架
2014/07/13 Python
解密Python中的描述符(descriptor)
2015/06/03 Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
2018/02/11 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
2018/06/11 Python
python计算两个矩形框重合百分比的实例
2018/11/07 Python
Python GUI库PyQt5样式QSS子控件介绍
2020/02/25 Python
pytorch简介
2020/11/11 Python
意大利团购网站:Groupon意大利
2016/10/11 全球购物
英国比较机场停车场网站:Airport Parking Essentials
2019/12/01 全球购物
俄罗斯一家时尚女装商店:Charuel
2019/12/04 全球购物
欧姆龙医疗保健与医疗产品:Omron Healthcare
2020/02/10 全球购物
Conforama西班牙:您的家具、装饰和电器商店
2020/02/21 全球购物
留学推荐信(中英文版)
2015/03/26 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
JavaScript实现简单图片切换
2021/04/29 Javascript
详解Go语言Slice作为函数参数的使用
2021/07/02 Golang
DE1107机评
2022/04/05 无线电