在Python中检查成员存在

我经常想检查一个对象是否有成员。 一个例子是在函数中创建一个单例。 为此,您可以像这样使用hasattr

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance

但你也可以这样做:

class Foo(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Foo()
            return self.instance

一种方法更好吗?

编辑:添加@classmethod ...但请注意,这个问题不是关于如何创建一个单例,而是如何检查对象中成员的存在。

编辑:对于这个例子,一个典型的用法是:

s = Foo.singleton()

那么sFoo类型的一个对象,每次都是一样的。 而且,通常这种方法会被多次调用。


这些是两种不同的方法:№1是LBYL(看你跳跃之前)和№2是EAFP(比许可更容易要求原谅)。

Pythonistas通常建议EAFP更好,参数的风格是“如果一个进程在测试它的时间和你自己创建它的时间之间创建文件会怎样?”。 这个论点在这里不适用,但它是一般的想法。 例外情况不应被视为例外。

在你的情况下性能明智 - 因为设置异常管理器( try关键字)在CPython中非常便宜,而创建异常( raise关键字和内部异常创建)是相对昂贵的 - 使用方法№2将会引发异常只有一次; 之后,您只需使用该属性。


我只是想测量时间:

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance



class Bar(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Bar()
            return self.instance



from time import time

n = 1000000
foo = [Foo() for i in xrange(0,n)]
bar = [Bar() for i in xrange(0,n)]

print "Objs created."
print


for times in xrange(1,4):
    t = time()
    for d in foo: d.singleton()
    print "#%d Foo pass in %f" % (times, time()-t)

    t = time()
    for d in bar: d.singleton()
    print "#%d Bar pass in %f" % (times, time()-t)

    print

在我的机器上:

Objs created.

#1 Foo pass in 1.719000
#1 Bar pass in 1.140000

#2 Foo pass in 1.750000
#2 Bar pass in 1.187000

#3 Foo pass in 1.797000
#3 Bar pass in 1.203000

似乎尝试/除了更快。 这对我来说似乎也更易读,无论如何取决于案例,这个测试非常简单,也许你需要更复杂的测试。


这取决于哪种情况是“典型的”,因为例外应该模拟非典型的情况。 因此,如果典型情况是instance属性应该存在,那么使用第二种代码风格。 如果没有instance像有instance一样典型,则使用第一种方式。

在创建单例的具体情况中,我倾向于采用第一种方式,因为创建单例初始时间是典型的用例。 :-)

链接地址: http://www.djcxy.com/p/4919.html

上一篇: Checking for member existence in Python

下一篇: Using try vs if in python