我正在浏览PyMongo tutorial并且有一件我不理解的事情。
我们证明我们可以创建这样的数据库集合:
>>>client = MongoClient()
>>>print(client)
MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True)
>>>db = client.test_database
>>>print(db)
Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'test_database')
>>>collection = db.test_collection #posts is the collection.
>>>print(collection)
Collection(Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'test_database'), 'test_collection')
我最初的想法是:"他们是否确保为客户端添加test_database
属性,为数据库添加test_collection
属性以使其与教程一起使用?&# 34;但进一步的实验告诉我,我可以使用任何"属性名称"以这种方式创建数据库和集合。我请求!例如:
>>>client = MongoClient()
>>>db = client.foo
>>>print(db)
Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'foo')
>>>collection = db.bar
>>>print(collection)
Collection(Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'foo'), 'bar')
这在Python中是如何工作的?我通过阅读GitHub存储库中的pymongo文件试图理解它,但新手很难理解。
答案 0 :(得分:2)
MongoClient会覆盖“魔法”方法__getattr__
。每当您访问MongoClient对象上的属性时,该对象实际上不是对象的属性或属性,例如当您访问“test_database”时,Python解释器会调用:
client.__getattr__("test_database")
The implementation of MongoClient.__getattr__
然后创建一个Database对象并返回它。
数据库还会覆盖__getattr__
以返回任何名称的Collection。
这两个类都会覆盖__getitem__
,以便括号访问起作用:
client["test_database"]
答案 1 :(得分:1)
您需要在班级中实施__getattr__
方法才能使其正常运行
简单来说 - 每当您访问未在类中定义的属性时,将调用__getattr__
方法(实际上它稍微复杂一些)。见下面的例子:
class Database(object):
def __init__(self, host):
self.host = host
def __getattr__(self, name):
return Collection(name)
class Collection(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return '<Collection name={0}>'.format(self.name)
>>> db = Database('www.example.com')
>>> db.host
'example.com'
>>> db.foo
<Collection name=foo>
>>> db.bar
<Collection name=bar>
您可以在此处详细了解__getattr__
:
Python: how to implement __getattr__()?