简体   繁体   English

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

[英]Set class variable value, the value returned by a class method

I'm trying to create a class which maps to a mongoDB collection. 我正在尝试创建一个映射到mongoDB集合的类。

My code looks like this: 我的代码如下所示:

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'

I came across a situation where I need to assign the class variable _collection with the return value of get_collection . 我遇到了一种情况,需要为类变量_collection分配返回值get_collection I also tried _collection = Collection.get_collection() which also seems not to be working 我也尝试了_collection = Collection.get_collection() ,这似乎也不起作用

As a work-around, I subclassed Collection and set value of _collection in the child class. 作为解决方法,我将Collection子类化, _collection在子类中设置_collection值。

Would like to know any simple solution for this. 想知道任何简单的解决方案。

Thanks in advance 提前致谢

There are some design/syntax errors in your code. 您的代码中存在一些设计/语法错误。

  • When the line _collection = get_collection() executes, get_collection is not yet defined. 当行_collection = get_collection()执行时,尚未定义get_collection As a matter of fact, the whole Collection class is not yet defined. 实际上,整个Collection类尚未定义。

  • get_collection_by_name is not defined anywhere. get_collection_by_name不在任何地方定义。

EDIT OP updated the question so the below points may not be relevant anymore EDIT OP更新了问题,因此以下几点可能不再适用

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

  • Sometimes you are passing a parameter to get_collection and sometimes you don't, however get_collection 's signature never accepts a parameter. 有时您将参数传递给get_collection ,有时却没有,但是get_collection的签名从不接受参数。

  • Calling get_collection will lead to an infinite recursion. 调用get_collection将导致无限递归。


You have to take a step back and reconsider the design of your class. 您必须退后一步,重新考虑课程的设计。

As DeepSpace mentions, here: 如DeepSpace所述,在这里:

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

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

the get_collection method is not yet defined when you call it. get_collection方法get_collection未定义。 But moving this line after the method definition won't work either, since the method depends on the Collection class (passed as cls to the method), which itself won't be defined before the end of the class Collection: statement's body. 但是,在方法定义之后移动此行也行不通,因为该方法取决于Collection类(作为cls传递给该方法),而class Collection:本身不会在class Collection:语句的正文结束之前定义。

The solution here is to wait until the class is defined to set this attribute. 解决方案是等到定义了类来设置此属性。 Since it looks like a base class meant to be subclassed, the better solution would be to use a metaclass: 由于它看起来像是要继承的基类,因此更好的解决方案是使用元类:

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

Note however that if Collection actually inherit from a another class already having a custom metaclass (ie Django Model class or equivalent) you will need to make CollectionType a subclass of this metaclass instead of a subclass of type . 但是请注意,如果Collection实际上从已经具有自定义元类的另一个类(即Django Model类或等效类)继承,则需要使CollectionType成为此元类的子类,而不是type的子type

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM