7

对于原始类型,我可以使用 if in : boolean check。但是,如果我使用 in 语法来检查类成员的存在,我会得到一个 NameError 异常。Python中有没有一种方法可以毫无例外地进行检查?或者是除了块之外的唯一方法?

这是我的示例代码。

class myclass:
    i = 0
    def __init__(self, num):
        self.i = num

mylist = [1,2,3]
if 7 in mylist:
    print "found it"
else:
    print "7 not present"  #prints 7 not present


x = myclass(3)
print x.i       #prints 3

#below line NameError: name 'counter' is not defined
if counter in x:
    print "counter in x"
else:
    print "No counter in x"
4

4 回答 4

17

您可以使用hasattr

if hasattr(x, 'counter'):
    # whatever
于 2013-07-11T10:57:09.133 回答
9

您得到的错误是因为您使用的是counter(名称)而不是'counter'(字符串)。但是,即使您要使用'counter'它也不会达到您的预期,您会得到TypeError: argument of type 'a' is not iterable- 即您无法迭代您的自定义对象。

相反,使用hasattr(感谢 Jon 的建议)。

>>> x = A(3)
>>> x.i
3
>>> hasattr(x, 'counter')
False
>>> hasattr(x, 'i')
True
于 2013-07-11T10:58:56.623 回答
2

您可以__contains__在您的类中创建一个函数,该函数使用运算符报告类中的哪些属性in

class myclass:

    def __init__(self, num):
        self.i = num

    def __contains__(self, attribute_name):
        return hasattr(self, attribute_name)

然后(几乎)与您的代码相同的代码会很好地工作。

x = myclass(3)
print x.i       #prints 3

# prints 'No counter in x'
if 'counter' in x:
    print "counter in x"
else:
    print "No counter in x"

请注意,您需要传递属性名称的字符串,而不是属性本身。

于 2013-07-11T11:08:32.770 回答
0

您的问题的正确答案在某种程度上取决于您所说的对象中存在的成员的含义。如果您的意思是,给定对象上是否存在实例变量,请hasattr按照其他答案的解释使用。

但是,如果您正在创建自己的集合类型并希望检查其内容中的特定值,那么您将希望为您的类提供一个__contains__方法。调用该魔术方法来实现in运算符。这是一个简单的例子,我只是在我自己的对象中包装了一个列表。

class MyListWrapper(object):
    def __init__(self, iterable=[]):
        self.list = list(iterable)

    def __contains__(self, value):
        return value in self.list

测试环节:

>>> m = MyListWrapper(["foo", "bar"])
>>> "foo" in m
True
于 2013-07-11T11:39:35.110 回答