首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于PyMongo的RAII风格API包装器

用于PyMongo的RAII风格API包装器
EN

Code Review用户
提问于 2015-10-07 19:45:17
回答 1查看 162关注 0票数 3

我刚刚看到了雷蒙德·赫廷格的谈话如何使Pythonic更简洁,并意识到我应该将他的许多想法付诸实践,特别是将API包装在一个使一切变得更简单和易于使用的类中。下面是我包装PyMongo所做的工作:

代码语言:javascript
复制
from pymongo import MongoClient

class MongoDB(object):
    """Provides a RAII wrapper for PyMongo db connections.
    Available collection functions limited to those in
    attributes_to_pass. Number of simultaneous connection 
    users also tracked. """

    attributes_to_pass = ["update", "insert", "count"]
    client = None
    num_users = 0

    def __init__(self, db, collection):
        MongoDB.client = MongoDB.client or MongoClient()
        self.collection = MongoDB.client[db][collection]
        MongoDB.num_users += 1

    def __enter__(self, *args):
        return self

    def __exit__(self, type, value, traceback):
        MongoDB.num_users -= 1
        if MongoDB.num_users is 0:
            self.client.close()

    def __getattr__(self, attr):
        if attr in MongoDB.attributes_to_pass:
            return getattr(self.collection, attr)
        else:
            return getattr(self, attr)

def main():
    with MongoDB(db = "db1", collection = "c1") as m:
        print(m.count())
        m.update({"jello":5} , {"hello":"you"}, upsert = True)
        print(m.count())
        m.insert({"joe":6})
        with MongoDB(db ='db1', collection = 'c2') as j:
            j.insert({"joe":6})
            print(j.count())

if __name__ == "__main__":
    main()

我非常感谢所有关于如何使这件事变得更好的建议。

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-10-08 11:23:32

太好了,你提供了一个文档字符串!但是,您犯了一个小格式错误,在简短的单行摘要和其余的docstring之间应该有一个空行。在样式指南中推荐它部分用于可读性,部分用于脚本解析器。

代码语言:javascript
复制
class MongoDB(object):
    """Provides a RAII wrapper for PyMongo db connections.

    Available collection functions limited to those in
    attributes_to_pass. Number of simultaneous connection 
    users also tracked. """

看起来attributes_to_pass实际上是一个常数。如果是这样的话,UPPER_SNAKE_CASE就应该清楚地知道它是这样的,特别是当它与经常变化的属性(如clientnum_users )混合时。它也应该是一个元组,因为元组是不可变的,所以除非在源代码中更新,否则不会改变。

代码语言:javascript
复制
ATTRIBUTES_TO_PASS = ("update", "insert", "count")

此外,当您调用这些常量时,您将引用类名。虽然这是可能的,但我个人认为它的可读性较低。我还以为你是在召唤一个你刚导入的类呢。您可以只传递self而不是类名。

代码语言:javascript
复制
def __getattr__(self, attr):
    if attr in self.ATTRIBUTES_TO_PASS:
        return getattr(self.collection, attr)
    else:
        return getattr(self, attr)
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/106868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档