Home Set class variable value, the value returned by a class method

# Set class variable value, the value returned by a class method

akhilsp
1#
akhilsp Published in 2018-02-12 14:22:03Z
 I'm trying to create a class which maps to a mongoDB collection. 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. I also tried _collection = Collection.get_collection() which also seems not to be working As a work-around, I subclassed Collection and set value of _collection in the child class. Would like to know any simple solution for this. Thanks in advance
bruno desthuilliers
2#
bruno desthuilliers Reply to 2018-02-12 14:45:53Z
 As DeepSpace mentions, here: 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. 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. 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.
DeepSpace
3#
 There are some design/syntax errors in your code. When the line _collection = get_collection() executes, get_collection is not yet defined. As a matter of fact, the whole Collection class is not yet defined. get_collection_by_name is not defined anywhere. EDIT OP updated the question so the below points may not be relevant anymore collection = get_collection(collection_name) should be 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. Calling get_collection will lead to an infinite recursion. You have to take a step back and reconsider the design of your class.