Python 如何区分hasattr和uu getattr_uuu中的普通属性访问?

Python 如何区分hasattr和uu getattr_uuu中的普通属性访问?,python,Python,请查看\uu getattr\uuu中的注释。我该怎么做?我正在使用Python3。原因是我想动态创建属性,但我不想在使用hasattr时这样做。谢谢。你不能不作弊。正如上面所说: 这[即,hasattr]是通过调用getattr(object,name)并查看它是否引发异常来实现的 换句话说,如果不阻止getattr,就无法阻止hasattr,这基本上意味着如果您关心访问属性,就根本无法阻止hasattr 我所说的“作弊”是指聪明人喜欢在这里发布的解决方案之一,它涉及到基本上所有Python的

请查看
\uu getattr\uuu
中的注释。我该怎么做?我正在使用Python3。原因是我想动态创建属性,但我不想在使用hasattr时这样做。谢谢。

你不能不作弊。正如上面所说:

这[即,
hasattr
]是通过调用
getattr(object,name)
并查看它是否引发异常来实现的

换句话说,如果不阻止
getattr
,就无法阻止
hasattr
,这基本上意味着如果您关心访问属性,就根本无法阻止
hasattr

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


您可以看到类似的问题和一些讨论。

此讨论适用于Python 3。(事实证明它也适用于Python 2.7)

不完全是您描述的方式,但以下几点可能会有所帮助:

  • \uuuu getattr\uuuu
    只有在正常方式下找不到属性时才会被访问
  • hasattr()
    检查是否引发了AttributeError
看看下面的代码是否有帮助

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')

您的代码抛出一个错误。调用
print('c={}.format(a.c))
后,它抛出
AttributeError:'a'对象没有属性“c”
。顺便说一下,如果属性是通过点符号a.c访问的,或者通过调用hasattr(a,'c')检查的,那么代码不会记录。所以它没有回答这个问题。代码正在运行,只是用Python2.7和Python3.6进行了测试。我在repl.it上用两个Python版本测试了您的代码:和。它们都抛出相同的
AttributeError
。从未使用过。在本机pythonshell(idle)和jupyter上运行代码,请在它们上尝试。代码是合法的,看起来像是你使用的网站上的一个bug。
>>> class A:
...     def __init__(self, a=1, b=2):
...         self.a = a
...         self.b = b
...
...     def __getattr__(self, name):
...         print('calling __getattr__')
...         print('This is instance attributes: {}'.format(self.__dict__))
...
...         if name not in ('c', 'd'):
...             raise AttributeError()
...         else:
...             return 'My Value'
...         return 'Default'
>>>         
>>> a = A()
>>> print('a = {}'.format(a.a))
a = 1
>>> print('c = {}'.format(a.c))
calling __getattr__
This is instance attributes: {'a': 1, 'b': 2}
c = My Value
>>> print('hasattr(a, "e") returns {}'.format(hasattr(a, 'e')))
calling __getattr__
This is instance attributes: {'a': 1, 'b': 2}
hasattr(a, "e") returns False
>>>