Question

I do apologize if this question is already answered on SO or if my problem could be solved by a simple Google search, but I don't know the terminology to describe it, other than the question title, which didn't turn up any results.

Because I don't know the terminology, the best I can do is give an example of what I want.

class MyClassProperty():
    def __init__(self):
        # somehow access MyObject class
        pass

class MyObject():
    var = MyClassProperty()

MyClassProperty will not only need to reference the MyObject class, otherwise it would be simple. The end goal is to be able to automatically add methods and variables to the MyObject class when a MyClassProperty is instantiated at class level.

I have seen frameworks and libraries do this before, the one that first comes to mind is Kivy, with its properties.

Thanks for any help you can give, even if the extent of that help is to tell me this is impossible.

Was it helpful?

Solution

It looks like you might want traits.

The only existing Python implementation I could find on a cursory search is here: http://code.enthought.com/projects/traits.

Multiple inheritance might also work for you.

class Some(object):
  a = 97
  b = 98
  def f(self):
    return self.a + self.b + self.c

class Other(object):
  c = 99

class Thing(Some, Other, object):
  pass

o = Thing()
p = Thing()
p.a, p.b, p.c = 65, 66, 67

print o.a, o.b, o.c, o.f() # 97 98 99 294
print p.a, p.b, p.c, p.f() # 65 66 67 198    

OTHER TIPS

Explicit is better than implicit. The idiomatic way to handle composition is using "mixins":

class MyFooMixin():
    def foo(self):
        print("I have a foo")

class MyBarMixin():
    def bar(self):
        print("This is a bar, where is my beer?")

class MyObject(MyFooMixin, MyBarMixin):
    pass

>>> x = MyObject()
>>> x.foo()
I have a foo
>>> x.bar()
This is a bar, where is my beer?

That said, at some implementations you can inspect the current frame. This is a naive approach to get you started (I'm sure it is wrong but I don't feel like digging all the frame structure stuff in order to write a proper implementation):

class Foo(object):
    _instantiators = []
    def __init__(self):
        try:
            raise Exception("foo")
        except Exception as foo:
            for frame in reversed(inspect.stack()):
                try:
                    for line in frame[4]:
                        if line.startswith('class '):
                            class_name = re.match(r'class\s+(\S+?)\(', line).group(1)
                            self._instantiators.append(frame[0].f_globals[class_name])
                            break
                except (IndexError, TypeError):
                    pass

class Bar(object):
    foo = Foo()

if __name__ == '__main__':
    bar = Bar()
    print Foo._instantiators

This abominable hack will print:

[<class '__main__.Bar'>]

This is probably wrong in so many ways, but Python is very hackable (my second programming language was Lisp, after BASIC, in Python I miss lispy features like hygienic macros and tail call optimization).

I'm nor sure whether I got you correctly, but is this what you want?

class MyObject(object):

    def __init__(self):
        pass

    def my_class_property(self):
        self.property_a = []
        self.property_b = 42

my_object = MyObject()
print my_object.property_a #fails
my_object.my_class_property()
print my_object.property_a
print my_object.property_b
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top