Python 中如何实现 a.xxx 返回 a 本身?

2017-08-26 19:11:07 +08:00
 sdjl
我想要实现一个功能,有 class A,a = A(),a == None 返回 True,同时 a.xxx (其中 xxx 可以随表写)返回 a 本身。

下面说说我的目的,我经常有这样的代码:

if a and a.b and a.b.c and a.b.c.d:
# do something

我觉得这样写太丑了,所以希望可以直接写成:

if a.b.c.d:
# do something

目前我写了一个代码,如下:



运行此代码时抛出异常:
Traceback (most recent call last):
File "test.py", line 19, in <module>
print a.sdjl
RuntimeError: maximum recursion depth exceeded
5020 次点击
所在节点    Python
29 条回复
yangff
2017-08-27 01:29:55 +08:00
PS: 更合理的做法是

>>> class A:
... def __getattr__(self, key):
... if (key.startswith('_')):
... raise AttributeError
... return self
oott123
2017-08-27 01:32:10 +08:00
你有没有想过,a.anything 都返回 a 的话,你就拿不到 a 上任何东西了…
比如 product.shop 返回 product,那么 product.shop.mall 也返回 product,product.shop.mall.address 也返回 product,这…
yangff
2017-08-27 01:34:23 +08:00
@oott123 他的意思是制造一个 blackhole 来使得 none.xxx 不崩溃且 blackhole==none 成立
guyskk
2017-08-27 10:34:22 +08:00
你这是在挖坑啊,到处是 N+1 查询,按你的描述 product.shop.mall.address 就要查 2 次数据库,多写几行就几十次了
explist
2017-08-27 11:55:30 +08:00
描述器看看?
sdjl
2017-08-27 14:40:09 +08:00
@yangff 非常感谢,此方法可行! 能解释一下为什么这样可以么?
sdjl
2017-08-27 14:41:19 +08:00
@guyskk 宁可多费机器一分,不费程序员一秒,体育老师没教过么~
yangff
2017-08-27 15:07:25 +08:00
@sdjl 你 print 的时候,python 会尝试把 object 搞成字符串,这会导致 python 尝试调用__repr__或者__str__
正常的 class A 会导致 AttributeError,于是 python 就知道不能这么操作。
你的 class A 则是这样的
a.__repr__ = a.__str__ = a.__call__ = a
于是,首先 python 获得 a.__repr__,然后尝试调用 a.__repr__(a),因为 a 不是函数,但是 a.__call__也就是 a.__repr__.__call__存在,所以会尝试执行 a.__repr__.__call__(),因为 a.__repr__.__call__ = a.__call__ = a, 所以 a.__repr__.__call__()又会去找 a.__repr__.__call__.__call__然后执行它……
于是就无限递归啦
sdjl
2017-08-27 15:10:44 +08:00
@yangff 明白了,非常感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/386003

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX