On 12/23/2010 10:13 AM, Alan Gauld wrote:

"Rasjid Wilcox" <rasj...@gmail.com> wrote

I've been playing with dynamically generated classes.  In particular:

class ClassMaker(object):
   def __init__(maker_self, name):
       maker_self.name = name
       #
       class Foo(object):
           def __init__(self):
               self.parent = maker_self
           def whoami(self):
               print 'I am a Foo instance made by %s' % self.parent.name
       maker_self.Foo = Foo

I'd probably just define the classes in a module rather than in the
init method itself. Then pass the required class to the parent init
as an argument. But the example code doesn't give enough clue
as to how these classes will be used to be sure that will suit
your need.

a = ClassMaker('Alice')
af = a.Foo()
ab = a.Bar()
af.whoami()
I am a Foo instance made by Alice
ab.whoami()
I am a Bar instance made by Alice
a.Foo is b.Foo
False

The actual use case is a system where there are multiple databases of
essentially the same form, where a is database A, and b is database B,
and Foo and Bar represent tables in both the databases.

Unless you are actually building a database it would be unusual to have
a class represent a table, a table normally represents a class - ie its not
a two way relation - or the class uses a table to populate attributes.
But again we have no clues about what the classes actually do - its
normally the methods of the class that define its usage...

the Foo table in database A, and bf would be the Foo table in database
B.

That sounds like you may be trying to create a facade pattern?

My question is: is there a better way?  Based on my playing with the
above, it all seems to do what I want.  My only concern is that I've
not seen this idiom before, and perhaps there is a simpler or more
standard way?

I think it will do what you want but I wouldn't bother putting the class
definitions inside the init - unless there is a good reason. At the very
least I would create two factory methods which are called by init.
That would allow you to reset the classes if needed too.

class A:
 def __init__(self, name):
       self.foo = makeFoo()
       self.bar = makeBar()
 def makeFoo(self):
        class Foo: pass
        return Foo
 def makeBar(self):
        class Bar: pass
        reurn Bar

But I still think its much more flexible to define the classes in a
separate module:

import foo, bar

class A:
   def __init__(self,foo,bar):
        self.foo = foo
        self.bar = bar

a = A(foo.Foo(A),bar.Bar(A))  # pass A so Foo/Bar know their parent

You can then extend the use of A without changing A by defining
new derivatives of Foo and Bar (as you use new databases for
example)

HTH,


By the way Alan your solution is simple and beautiful!
I like this kind of flexible design.

Regards
Karim
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to