我看到了如下代码(来自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)
...
?如果不是,它们之间有什么区别?
答案 0 :(得分:1)
@property
装饰器用于调用方法看起来像调用实例。
因此,如果您有一个Model
实例,则可以通过调用db
看起来像db
属性的内容来获取新数据库对象,但是实际上是db
方法:
>>> 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()
答案 1 :(得分:1)
存在差异......
方法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时,都会创建一个新的数据库实例。
答案 2 :(得分:0)
当它被调用时,它会创建一个新的数据库实例,类似于第二个替代实例。这意味着每次调用insert
都会创建一个新的数据库实例,插入然后删除数据库实例,因为没有任何引用指向它。
在您的第一个替代方案中,您将始终访问相同的实例。这意味着在调用insert之后,Database对象仍然存在。