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
4991 次点击
所在节点    Python
29 条回复
sdjl
2017-08-26 19:19:16 +08:00
前 20 个回复必感谢!
ivechan
2017-08-26 19:22:53 +08:00
你直接把代码块 a.b.c.d try 一下不就行了。
kotlin 倒是有处理你这种问题的解决方法,Python 我还没见过。。
sdjl
2017-08-26 19:25:21 +08:00
@ivechan 那不是一样丑么
xkoing
2017-08-26 19:28:34 +08:00
honmaple
2017-08-26 19:30:01 +08:00
没看懂什么需求, a 必定不为 None 啊,或者只要__getattr__
WangYanjie
2017-08-26 19:45:47 +08:00
```
>>> 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-08-26 19:47:49 +08:00
我这样回复你也感谢?
Cooky
2017-08-26 19:56:59 +08:00
try 最省事,最明白
zwgmlr3
2017-08-26 20:07:16 +08:00
if xxx(a,'a.b.c.d'): pass
zwgmlr3
2017-08-26 20:23:44 +08:00
```
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-08-26 20:25:37 +08:00
hahastudio
2017-08-26 21:09:24 +08:00
好问题,这个语法类似于 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-08-26 21:19:24 +08:00
第一次见到这么奇怪的需求。。。这个有什么用吗?
sdjl
2017-08-27 00:05:37 +08:00
@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-08-27 00:11:54 +08:00
这样,如果我有一个 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-08-27 00:14:19 +08:00
前排帮顶 蹭个感谢
ToBeHacker
2017-08-27 00:53:36 +08:00
直接用,try 一下就行了。 改函数的话更麻烦,要使用异常检查的机制啊。
二楼正解
byx
2017-08-27 01:09:17 +08:00
yangff
2017-08-27 01:25:45 +08:00
>>> class A:
... def __getattr__(self, key):
... return self
... def __repr__(self):
... return 'None'
...
simadad
2017-08-27 01:28:11 +08:00
这个有需求很像 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