设置类变量值,类方法返回的值

时间:2018-02-12 14:22:04

标签: python python-3.x class

我正在尝试创建一个映射到mongoDB集合的类。

我的代码如下所示:

class Collection:
    _collection = get_collection()  # This seems not working

    @classmethod
    def get_collection(cls):
        collection_name = cls.Meta.collection_name if cls.Meta.collection_name \
        else cls.__name__.lower()
        collection = get_collection_by_name(collection_name) # Pseudo code, please ignore
        return collection

    class Meta:
        collection_name = 'my_collection'

我遇到了一种情况,我需要为类变量_collection分配返回值get_collection。 我也试过_collection = Collection.get_collection(),似乎也没有工作

作为解决方法,我将Collection子类化,并在子类中设置_collection的值。

想知道任何简单的解决方案。

提前致谢

2 个答案:

答案 0 :(得分:2)

您的代码中存在一些设计/语法错误。

  • 当行_collection = get_collection()执行时,尚未定义get_collection。事实上,尚未定义整个Collection类。

  • get_collection_by_name未在任何地方定义。

编辑 OP更新了问题,因此以下几点可能不再相关

  • collection = get_collection(collection_name)应该是collection = cls.get_collection(collection_name)

  • 有时您将参数传递给get_collection,有时您不会,但get_collection的签名永远不会接受参数。

  • 调用get_collection将导致无限递归。


你必须退后一步,重新考虑你班级的设计。

答案 1 :(得分:2)

正如DeepSpace所提到的,这里:

class Collection:
    _collection = get_collection()  # This seems not working

    @classmethod
    def get_collection(cls):
        # code that depends on `cls`

调用它时尚未定义get_collection方法。但是在方法定义之后移动这一行也不会起作用,因为该方法取决于Collection类(作为cls传递给方法),它本身不会被定义在class Collection:声明正文结束之前。

这里的解决方案是等到定义类来设置此属性。因为它看起来像是一个要被子类化的基类,所以更好的解决方案是使用元类:

class CollectionType(type):
    def __init__(cls, name, bases, attrs):
        super(CollectionType, cls).__init__(name, bases, attrs)
        cls._collection = cls.get_collection()


# py3
class Collection(metaclass=CollectionType):
    # your code here


# py2.7
class Collection(object):
    __metaclass__ = CollectionType
    # your code here

但请注意,如果Collection实际上从已经拥有自定义元类的另一个类(即Django Model类或等效类)继承,则需要使CollectionType成为此元类的子类而不是type的子类。