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

2017 年 8 月 26 日
 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
5570 次点击
所在节点    Python
29 条回复
sdjl
2017 年 8 月 26 日
前 20 个回复必感谢!
ivechan
2017 年 8 月 26 日
你直接把代码块 a.b.c.d try 一下不就行了。
kotlin 倒是有处理你这种问题的解决方法,Python 我还没见过。。
sdjl
2017 年 8 月 26 日
@ivechan 那不是一样丑么
xkoing
2017 年 8 月 26 日
honmaple
2017 年 8 月 26 日
没看懂什么需求, a 必定不为 None 啊,或者只要__getattr__
WangYanjie
2017 年 8 月 26 日
```
>>> class A(object):
... @property
... def xxx(self):
... return self
...
>>> a = A()
>>> a
<__main__.A object at 0x10e8809d0>
>>> a.xxx
<__main__.A object at 0x10e8809d0>
```
cheetah
2017 年 8 月 26 日
我这样回复你也感谢?
Cooky
2017 年 8 月 26 日
try 最省事,最明白
zwgmlr3
2017 年 8 月 26 日
if xxx(a,'a.b.c.d'): pass
zwgmlr3
2017 年 8 月 26 日
```
def hasattrs(obj, attrs):
attrs = attrs.split('.')
objs = attrs[0]
for attr in attrs[1:]:
if hasattr(obj, attr):
obj = eval('{}.{}'.format(objs, attr))
objs += '.{}'.format(attr)
else:
return False
return obj

class C():
d = 233


class B():
c = C()


class A():
b = B()


a = A()
print(hasattrs(a, 'a.b.c.d'))
print(hasattrs(a, 'a.b.e.d'))
```
大概这样
zwgmlr3
2017 年 8 月 26 日
hahastudio
2017 年 8 月 26 日
好问题,这个语法类似于 C# null-conditional operator https://msdn.microsoft.com/en-us/magazine/dn802602.aspx
if a?.b?.c?.d:
PEP 505 提出过这个想法 https://www.python.org/dev/peps/pep-0505/

如果你只是想要 class A 下面一层的话,那就是 getattr
但如果你想要语法层面的东西的话,还是一串 and 吧
VShawn
2017 年 8 月 26 日
第一次见到这么奇怪的需求。。。这个有什么用吗?
sdjl
2017 年 8 月 27 日
@VShawn

很有用,举个例子,假设有表 A,其中有一个字段名为 Bid,这个字段保存了表 B 的主键,用某种方法得到表 A 的某个数据 a 后,就可以用 a.b 直接得到表 B 的数据(其中 b 的 id 等于 a.Bid )

同理,可以 a.b.c.d 这样得到多个表的关联数据,例如:product.shop.mall.address

我的程序中大量使用了这样的代码,这样我就不用去操作数据库了,例如我有列表 products,现在需要得每个商品的商家列表,可以这样写:

shops = [p.shop fpr p in products]

注意,p.shop 这一步其实自动查询的表 Shop,如果我不调用 p.shop,就没有查表操作
sdjl
2017 年 8 月 27 日
这样,如果我有一个 product,我需要判断这个商品所在商家所在商场是否有地址信息,我就可以直接写成:

if product.shop.mall.address:
# do something

如果在其中某一步发现数据不存在,例如 shop 其实不存在,那么 shop 得到的其实就是我问题中提出的 class A 的实例 a。

此时 product.shop == None,且同时 product.shop.mall.address == product.shop.mall == producj.shop == None
PythonAnswer
2017 年 8 月 27 日
前排帮顶 蹭个感谢
ToBeHacker
2017 年 8 月 27 日
直接用,try 一下就行了。 改函数的话更麻烦,要使用异常检查的机制啊。
二楼正解
byx
2017 年 8 月 27 日
yangff
2017 年 8 月 27 日
>>> class A:
... def __getattr__(self, key):
... return self
... def __repr__(self):
... return 'None'
...
simadad
2017 年 8 月 27 日
这个有需求很像 django 里的 qureyset,可以借鉴下 django 的源码

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

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

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

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

© 2021 V2EX