7

我有一个变量,它可能会或可能不会在实例中获得值:

class EC():
   __init__(self, a=False):
   ...
   if a: self.__var = ...

稍后我想检查实例中是否存在__var。因为在名称前添加__会将内部名称更改为_EC__var,所以检查代码变得有点混乱:

if ''.join(['_',self.__class__.__name__,'__name']) in self.__dict__: ...

上面的代码是否被认为是正常的?如果不是,首选的替代方案是什么?

我能想到的一种选择是无论如何都给__var一些价值,例如:

_no_value = object()
...
   def __init__(self, a):
      self.__var = _no_value
      ...
      if a: self.__var = ...

所以稍后我可以将__var_no_value进行比较,而不是与内部变量进行比较。

4

4 回答 4

11

只需使用 hasattr(self, '_var') 来查看它是否存在 - 它可以设置为 None 但如果 hasattr 说它存在,它就会存在。

例如:

>>> class a():
...   def __init__(self):
...      self.a = 3
...      self._a_ = 4
...      self.__a__ = 'Fred'
...
>>> A=a()
>>> hasattr(a, 'a')
False
>>> hasattr(A, 'a')
True
>>> hasattr(A, '_a_')
True
>>> hasattr(A, '__a__')
True
>>> hasattr(A, '__b__')
False
>>>
于 2013-08-01T14:25:26.197 回答
11

您忘记了EAFP 原则

try:
    value = self.__var
except AttributeError:
    # do something else

如果您决定使用哨兵,可以将其与类变量结合使用:

class EC():
    __var = object():
    ...
    if self.__var is not EC.__var:
        ...
于 2013-08-01T14:48:31.743 回答
4

只需将其设置None 为类

 class EC():
    __var = None

    __init__(self, a=False):
        ...
        if a: self.__var = ...

然后测试if self.__var is not None.

如果None应该是属性的有效值,请使用不同的单例哨兵:

_sentinel = object()

 class EC():
    __var = _sentinel

    __init__(self, a=False):
        ...
        if a: self.__var = ...

并测试if self.__var is not _sentinel.

这样,所有对的引用__var都被正确地重写以包含类名。

The other path would be to not use double-underscore names for your attributes. __var should only be used for attributes you want to namespace to your specific class so that subclasses do not accidentally clobber it with their own attributes.

In other words, do not use double-underscore names unless you really understand what they are for and actually need it. Any code that is not part of a framework for wider consumption by unknown third parties? Just stick to single underscores instead.

于 2013-08-01T14:28:37.540 回答
1

我想有一个简单的方法可以检查出来。这是我尝试的方式。

class Test:

    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

        if self.c:
            self.d = "The variable exists"
        if 'd' in self.__dict__:
            print(self.d)

现在实例化上面的类:

t = Test('123', 'asd', True)

上面的代码输出类似:

The variable exists

如果您想查看self.__dict__. 只需键入:print(self.__dict__) 上述代码的输出将类似于:

{'a': '123', 'b': 'asd', 'c': True, 'd': 'The variable exists'}

所有的实例变量都以字典的形式存储在 self. 听写

我在 python 3.8.1 和 python 2.6.6 中试过这个。它成功了。如果对答案有任何误解,请通过评论反馈。

于 2020-03-13T05:32:31.990 回答