我正在尝试创建一个映射到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
的值。
想知道任何简单的解决方案。
提前致谢
答案 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
的子类。