 
|  |      1sdjl OP 前 20 个回复必感谢! | 
|      2ivechan      2017-08-26 19:22:53 +08:00  1 你直接把代码块 a.b.c.d try 一下不就行了。 kotlin 倒是有处理你这种问题的解决方法,Python 我还没见过。。 | 
|  |      4xkoing      2017-08-26 19:28:34 +08:00  1 | 
|  |      5honmaple      2017-08-26 19:30:01 +08:00  1 没看懂什么需求, a 必定不为 None 啊,或者只要__getattr__ | 
|      6WangYanjie      2017-08-26 19:45:47 +08:00  1 | 
|  |      7cheetah      2017-08-26 19:47:49 +08:00  3 我这样回复你也感谢? | 
|  |      8Cooky      2017-08-26 19:56:59 +08:00 via Android  1 try 最省事,最明白 | 
|  |      9zwgmlr3      2017-08-26 20:07:16 +08:00 via Android  1 if xxx(a,'a.b.c.d'): pass | 
|  |      10zwgmlr3      2017-08-26 20:23:44 +08:00  1 ``` 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')) ``` 大概这样 | 
|  |      11zwgmlr3      2017-08-26 20:25:37 +08:00  2 | 
|  |      12hahastudio      2017-08-26 21:09:24 +08:00  2 好问题,这个语法类似于 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 吧 | 
|  |      13VShawn      2017-08-26 21:19:24 +08:00 via Android  1 第一次见到这么奇怪的需求。。。这个有什么用吗? | 
|  |      14sdjl OP @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,就没有查表操作 | 
|  |      15sdjl OP 这样,如果我有一个 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 | 
|      16PythonAnswer      2017-08-27 00:14:19 +08:00 via Android  1 前排帮顶 蹭个感谢 | 
|  |      17ToBeHacker      2017-08-27 00:53:36 +08:00  1 直接用,try 一下就行了。 改函数的话更麻烦,要使用异常检查的机制啊。 二楼正解 | 
|  |      18byx      2017-08-27 01:09:17 +08:00  1 | 
|      19yangff      2017-08-27 01:25:45 +08:00  1 >>> class A: ... def __getattr__(self, key): ... return self ... def __repr__(self): ... return 'None' ... | 
|      20simadad      2017-08-27 01:28:11 +08:00 via Android  1 这个有需求很像 django 里的 qureyset,可以借鉴下 django 的源码 | 
|      21yangff      2017-08-27 01:29:55 +08:00  1 PS: 更合理的做法是 >>> class A: ... def __getattr__(self, key): ... if (key.startswith('_')): ... raise AttributeError ... return self | 
|  |      22oott123      2017-08-27 01:32:10 +08:00 via Android 你有没有想过,a.anything 都返回 a 的话,你就拿不到 a 上任何东西了… 比如 product.shop 返回 product,那么 product.shop.mall 也返回 product,product.shop.mall.address 也返回 product,这… | 
|      23yangff      2017-08-27 01:34:23 +08:00  2 | 
|  |      24guyskk      2017-08-27 10:34:22 +08:00 via Android  1 你这是在挖坑啊,到处是 N+1 查询,按你的描述 product.shop.mall.address 就要查 2 次数据库,多写几行就几十次了 | 
|  |      25explist      2017-08-27 11:55:30 +08:00  1 描述器看看? | 
|      28yangff      2017-08-27 15:07:25 +08:00  2 @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__然后执行它…… 于是就无限递归啦 |