社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

会变 "魔术" 的 Python,文末公布中奖结果

Python之禅 • 7 年前 • 333 次点击  

Python 最吸引你的地方是什么?

整洁的代码缩进格式?丰富的第三方包?更高的开发效率?还是良好的跨平台性?

这些特性都不足以说明 Python 的优点,最吸引人的应该是动态性所带来的灵活与便利性。

你可能听过说一个词叫做「鸭子类型」,所谓鸭子类型就是只要它走路像鸭子,叫起来像鸭子,那么你就可以认为它是鸭子

而 Python 就有这种魔力使得任何东西都可以是鸭子,这种魔力就源自于语言的动态性, Python 提供了很多魔术方法,使得鸡可以像鸭子一样游泳

所谓魔术方法就是由 Python 内部定义,具有特殊作用的方法,这些方法有一个共同特征,以双下划线开始并以双下划线结尾,比如对象的初始化方法 __init__,是最常用的一个魔术方法(不少初学者以为只有一个下划线,在这栽了跟头

如何使用这些魔术方法呢?

先来看一个例子

我们都知道数字可以相加,字符串也可以相加

>>> 1+2
3
>>> "hello"+" Python"
'hello Python'

列表也可以相加

>>> [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]

那么两个对象(这里特指类的实例对象)可不可以相加呢?

class Point:
   def __init__(self, x, y):
       self.x = x
       self.y = y

   def __repr__(self):
       return "Point({}, {})".format(self.x, self.y)

>>> (Point(1, 2) + Point(3, 4))
Traceback (most recent call last):
 File "", line 1, in
TypeError: unsupported operand type(s) for +: 'Point' and 'Point'
>>>

上面用 Point 类表示坐标系中的一个点,x,y 分别代表横轴和纵轴,两个点相加时报错了,错误日志告诉我们,对于 Point 类不支持 「+」操作。

但如果你实现了魔术方法 __add__ 就可以支持加操作了

class Point:
   ...

   def __add__(self, other):
       assert isinstance(other, Point)
       return Point(self.x + other.x, self.y + other.y)

再来运行:

>>> Point(1, 2) + Point(3, 4)
Point(4, 6)

再举一个例子

我们知道类的属性一般都是用点操作获取属性,例如p.x,p.y,而访问字典对应的key值都是通过 p[‘x’] 或者 p.get(“x”) 来访问的,那字典可不可以用 “.” 的方式获取呢?




    
>>> d = {"a":"b"}
>>> d.a
Traceback (most recent call last):
 File "", line 1, in
AttributeError: 'dict' object has no attribute 'a'

显然,默认情况下是不允许通过“.”的方式获取的,但是如果你实现了魔术方法__getattr__就可以使用点的方式获取了。

我们自定义一个类,继承 dict,再实现 __getattr__方法就可以用“.”操作了,当属性使用 a.b 的方式访问时,就会调用 __getattr__

>>> class MyDict(dict):
...    def __getattr__(self, item):
...        return self.get(item)
...
>>> d = MyDict(a="b")
>>> d
{'a': 'b'}
>>> d['a']
'b'
>>> d.a
'b'

如果你熟悉 Django 中 Template 语法的话,你现在应该知道为什么字典对象可以使用“.”操作获取里面的元素。

当然,魔术方法远不止这两个,全部加起来有近百来个


  • 关于实例构建与初始化的,比如 __new__,__init__

  • 关于属性访问控制:__getattr__,__setattr__

  • 描述符相关的:__get__, __set__

  • 关于操作容器的: __getitem__,__setitem__

  • 关于上下文管理的:__enter__,__exit__

  • 比较运算符:__cmp__,__eq__,__lt__,__gt__

  • 算术运算符:__add__,__sub__,__mul__,__div__


回复 「magic」可获取一份完整的魔术方法介绍文档。你是使用Python过程,使用过哪些魔术方法来做一些特殊的黑科技操作呢?欢迎留言





周一赠书《年前福利,送书10本》中奖结果出来啦,恭喜以下同学:


@fly swallow

@wowking

@动感光波

@Michael

@李大侠@Mysoul@M-in @yanzu @叶知秋@玉观音
请以上同学尽快微信私信我,把你喜欢的书和联系地址发给我,2天内没发的将取消资格哦,快递要放假了

推荐阅读:

学Python,关注Python之禅


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/JigGSBYUHC
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/6647
 
333 次点击