【问题标题】:How to override nested "dot" operators?如何覆盖嵌套的“点”运算符?
【发布时间】:2020-01-18 19:30:57
【问题描述】:

如果我使用__getattr__ 并调用a.b.c,其中a 是我的类的一个实例,那么我会在__getattr__ 中得到"b",这意味着我也需要递归来覆盖访问c。但是如果递归,我不知道最后一次调用,所以我不知道什么时候返回最终值,即无法区分a.b(a.b).c

如何克服?

如何在覆盖操作中获取整个链“b”、“c”?


例如,A是我的班级,那么假设我想成为:

a = A()

print(a.b)  # prints "hello"
print(a.b.c) # prints "hi"

等等

即我想自己覆盖每个组合。

【问题讨论】:

  • 有什么具体的例子吗?

标签: python operator-overloading


【解决方案1】:

获取 b 属性可以动态创建某事物的实例:

class A:
    def __getattr__(self, name):
        if name == "b":
            return B()
        raise AttributeError(name)


class B:
    def __getattr__(self, name):
        if name == "c":
            return "hi"
        raise AttributeError(name)


a = A()
print(a.b.c)
# -> "hi"

【讨论】:

  • print(a.b) 怎么样?我希望它是“你好”,而不是 A 的实例!
  • print函数使用__str__,所以你可以在B类中定义这个方法。你能解释一下你真正想做的事吗?
  • 我不想限制自己的打印。我需要在表达式的末尾有特定的对象,它不应该和中间的一样。