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 ljust rjust center输出
Sep 06 Python
python3.0 字典key排序
Dec 24 Python
python实现的登陆Discuz!论坛通用代码分享
Jul 11 Python
Python模拟登录验证码(代码简单)
Feb 06 Python
python3 实现的人人影视网站自动签到
Jun 19 Python
python3判断url链接是否为404的方法
Aug 10 Python
Python中list的交、并、差集获取方法示例
Aug 01 Python
Python使用百度api做人脸对比的方法
Aug 28 Python
把vgg-face.mat权重迁移到pytorch模型示例
Dec 27 Python
Pytorch对Himmelblau函数的优化详解
Feb 29 Python
Django ValuesQuerySet转json方式
Mar 16 Python
OpenCV项目实践之停车场车位实时检测
Apr 11 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 xml留言板 xml存储数据的简单例子
2009/08/24 PHP
PHP+ajax 无刷新删除数据
2010/02/20 PHP
PHP生成数组再传给js的方法
2014/08/07 PHP
简单解决新浪SAE无法上传文件的问题
2015/05/13 PHP
PHP文件操作方法汇总
2015/07/01 PHP
php opendir()列出目录下所有文件的实例代码
2016/10/02 PHP
PHP流Streams、包装器wrapper概念与用法实例详解
2017/11/17 PHP
使用ucenter实现多站点同步登录的讲解
2019/03/21 PHP
PHP获取php,mysql,apche的版本信息及更多服务器信息
2021/03/09 PHP
List all the Databases on a SQL Server
2007/06/21 Javascript
JAVASCRIPT  THIS详解 面向对象
2009/03/25 Javascript
JavaScript代码编写中各种各样的坑和填坑方法
2014/06/06 Javascript
JavaScript中的object转换成number或string规则介绍
2014/12/31 Javascript
JS实现图片高亮展示效果实例
2015/11/24 Javascript
Javascript中的Prototype到底是什么
2016/02/16 Javascript
COM组件中调用JavaScript函数详解及实例
2017/02/23 Javascript
Bootstrap显示与隐藏简单实现代码
2017/03/06 Javascript
详解react、redux、react-redux之间的关系
2018/04/11 Javascript
python模拟Django框架实例
2016/05/17 Python
神经网络理论基础及Python实现详解
2017/12/15 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
如何验证python安装成功
2020/07/06 Python
关于老式浏览器兼容HTML5和CSS3的问题
2016/06/01 HTML / CSS
英国最出名高街品牌:Forever Unique
2018/02/24 全球购物
马歇尔耳机官网:Marshall Headphones
2020/02/04 全球购物
Booking.com亚太地区:Booking.com APAC
2020/02/07 全球购物
澳大利亚领先的在线药房:Pharmacy Online(有中文站)
2020/02/22 全球购物
研发工程师的岗位职责
2013/11/18 职场文书
派出所所长先进事迹
2014/05/19 职场文书
财务管理专业毕业生求职信
2014/06/02 职场文书
2014年底个人工作总结
2015/03/10 职场文书
商场营业员岗位职责
2015/04/14 职场文书
女方离婚起诉书
2015/05/18 职场文书
暂住证明怎么写
2015/06/19 职场文书
医护人员继续教育学习心得体会
2016/01/19 职场文书
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS