1

我看到了如下代码(来自https://github.com/daydayfree/diggit/blob/master/model/model.py):

from database import Database
...
class Model(object):
    @property
    def db(self): return Database()

    def insert(self, documents):
        return self.db.insert(self.table, documents)
...

主要目的@property是提供对Database()实例方法的访问,我正确吗?

那么我可以将其重写为:

from database import Database
...
class Model(object):
    def __init__(self):
        self.db = Database()

    def insert(self, documents):
        return self.db.insert(self.table, documents)

from database import Database
...
class Model(object):
    def db(self):
        return Database()

    def insert(self, documents):
        return self.db().insert(self.table, documents)
...

? 如果不是,它们之间有什么区别?

4

3 回答 3

1

装饰器@property用于使调用方法看起来像调用实例。

所以,如果你有一个Model实例,你可以通过调用看起来像属性的东西来获取一个的数据库对象,但实际上是方法:dbdbdb

>>> a = Model()
>>> a.db
Database()

在您的第一个“重写”示例中,您在类的方法中创建了一个db属性。__init__现在,每次调用db属性时,每次都会得到相同 Database的对象(__init__调用期间创建的对象),而不是之前的对象 。

想象一下,您可以从 python 标准库中return Database()替换。return random.random()在最初的实现中,每次调用都会返回一个新号码db。在您建议的实现中,每次都将返回相同的数字,因为random.random()只调用了一次(在__init__方法中),并且它的输出保存在db.

您的第二个“重写”基本上与原始实现相同,除了您将db作为方法调用(即使用开括号和闭括号)。

>>> a = Model()
>>> a.db()
Database()
于 2013-08-20T05:42:53.837 回答
1

有区别...

方法一:属性装饰器

class Model(object):
    @property
    def db(self): return Database() 

o = Model()
db1 = o.db  #a database instance. No brackets
db2 = o.db  #another database instance
o.db = foo  #error due to read only property

每次调用 db 时,它都会创建一个新的数据库实例。

方法2:初始化时设置db

class Model(object):
    def __init__(self):
        self.db = Database()

o = Model()
db1 = o.db  #a database instance
db2 = o.db  #the same database instance
o.db = foo  #works fine so long as foo is defined

每次访问 db 时,它都会返回相同的数据库实例。

方法3:db作为函数

class Model(object):
    def db(self):
        return Database()

o = Model()
db1 = o.db()  #a database instance. note the brackets
db2 = o.db()  #another database instance
o.db = foo    #works fine so long as foo is defined

每次调用 db 时,它都会创建一个新的数据库实例。

于 2013-08-20T05:46:15.780 回答
0

当它被调用时,它会创建一个新的数据库实例,类似于您的第二种选择。这意味着每次调用insert都会创建一个新的数据库实例,插入然后删除数据库实例,因为没有指向它的引用。

在您的第一个替代方案中,您将始终访问相同的实例。这意味着在调用插入之后,数据库对象仍然存在。

于 2013-08-20T05:35:11.000 回答