async-await - 如何在 hylang 中编写像点(。)运算符这样的宏?
问题描述
我们有一些异步属性(使用@property)和一些常用的。我们必须使用 hy 来检查一个是否是异步的,或者不使用 asyncio.iscoroutine 函数。问题是我们必须使用 getattr 而不是 。运算符,因为 dot 将调用属性内部函数。我们希望在不破坏其他项目中使用的 DSL 的情况下更改我们的 hy 代码,也就是说,我们不想对属性名称使用字符串表示法(双引号),因此我们需要编写一些像 . 但在内部调用 getattr。
=> (defmacro attr [obj attr] `(getattr ~obj '~attr))
=> (attr 5 real)
Traceback (most recent call last):
File "stdin-5bbedde10a6366314d9be4bd343639582b4d0748", line 1, in <module>
(attr 5 real)
AttributeError: 'int' object has no attribute 'real'
=> (. 5 real)
5
解决方案
听起来您对 Python 属性的语义感到困惑,这是可以理解的,因为它们相当多毛。在 Python 中(因此在 Hy 中也是等价的结构),foo.x
并且getattr(foo, "x")
总是等价的,即使x
是一个属性。要将属性方法作为对象而不是调用它,您需要检索类 ( type(x)
) 而不是实例的属性,并getattr
使用字符串文字并.
保持可互换。在这个例子中,getattr(type(foo), 'bar').fset
也可以写成type(foo).bar.fset
。