2

I'd like to do this:

class MyThing(object):
    def __init__(self,owning_cls):
        self.owning_cls = owning_cls

class MyClass(object):
    thing = MyThing(self.__class__)

print MyClass.thing.owning_cls

This doesn't work - as there isn't a self to refer to in the class construction of MyClass.

Is there any way to achieve this (it's clearly trivial if we make thing an instance attribute, but I'd like to be a class attribute please!)?

1
  • You can use a metaclass. Commented Jun 27, 2012 at 15:51

5 Answers 5

1

Perform the call immediately after the class declaration:

class MyClass(object): pass
MyClass.thing = MyThing(MyClass)
Sign up to request clarification or add additional context in comments.

Comments

1

Use a decorator. I find this to be a clean solution because it lets you keep more of the class definition together, rather than having to write additional class-related code after the class definition or forcing you to instantiate MyClass, etc.

class MyThing(object):
    def __init__(self,owning_cls):
        self.owning_cls = owning_cls

def set_thing(cls):
    cls.thing = MyThing(cls)
    return cls

@set_thing
class MyClass(object):
    pass

>>> print MyClass.thing.owner_cls
<class '__main__.MyClass'>

Comments

0

Maybe you can initialize the class with __new__?

Comments

0

Use desciptor:

class Ownable(object):
    def __init__(self, clz):
        self._clz = clz
        self._inst = None
    def __get__(self, inst, owner_clz):
        self._inst = self._inst or self._clz(owner_clz)
        return self._inst

class MyThing(object):
    def __init__(self, owner_clz):
        self.owner_clz = owner_clz

class MyClass(object):
    thing = Ownable(MyThing)

>>> print MyClass.thing.owner_clz
<class '__main__.MyClass'>

Comments

0

Ah, the use MetaClasses comment helps a lot here.

This looks like an "easy" way to achieve exactly what I want

class MyClassMetaclass(type):
    def __new__(cls, name, bases, dct):
        cls.thing = MyThing(name)
        return super(MyClassMetaclass, cls).__new__(cls, name, bases, dct)

class MyThing(object):
    def __init__(self,owning_cls):
        self.owning_cls = owning_cls

class MyClass(object):
    __metaclass__=MyClassMetaclass

print MyClass.thing.owning_cls

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.