python - 如何区分 __getattr__ 中的 hasattr 和普通属性访问?

标签 python

class a_class:
    def __getattr__(self, name):
        # if called by hasattr(a, 'b') not by a.b
        # print("I am called by hasattr")
        print(name)

a = a_class()
a.b_attr

hasattr(a, 'c_attr')

请看一下__getattr__里面的注释。我怎么做?我正在使用 Python 3。原因是我想动态创建属性,但我不想在使用 hasattr 时这样做。谢谢。

最佳答案

不作弊就不行。作为the documentation说:

This [that is, hasattr] is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.

换句话说,你不能在不阻止 getattr 的情况下阻止 hasattr,这基本上意味着你根本不能阻止 hasattr如果您关心访问属性。

我所说的“作弊”是指聪明人喜欢在此处发布的这些解决方案之一,这些解决方案涉及基本上所有 Python 的最终运行。它们通常涉及重新分配内置函数、检查/操纵调用堆栈、使用内省(introspection)来查看文字源代码、修改对象的“ secret ”内部属性​​等等。例如,您可以查看调用堆栈以查看 hasattr 是否在调用链中。这种类型的解决方案是可能的,但非常脆弱,有可能在未来的 Python 版本、非 CPython 实现中或在使用另一种同样丑陋和狡猾的 hack 的情况下被破坏。

可以看到类似的问题和一些讨论here .

关于python - 如何区分 __getattr__ 中的 hasattr 和普通属性访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18797897/

相关文章:

python&linux pip 总是尝试使用 python2.7 而不是 3.4

python - Upstart python脚本

Python学习环境

Python turtle 绘图更新为turtle.tracer(0,0)

python - 有人可以帮我理解 python 中的 for 循环吗

python - 如何监控 TensorFlow 估计器训练中的验证损失?

python - 将字符串与数字相乘会导致 "TypeError: can' t 将序列乘以 'str' 类型的非整数”

python - 如何从极地日期计算月份的开始和结束日期?

python - 如何使用 PynamoDB 在代码中使用访问凭据而不是环境变量

python - 根据模式匹配从 Redis 中删除对象