Re: Generating modul classes with eval

2005-02-03 Thread Axel Straschil
Hello!

 Note that we don't need eval anywhere.

Uuups, that looks realy cool! Thanks for that!

Im fooling around with generating html-tags. As there are only two kind
of html tags, one who can nest chields, and one who cant, i wantet to
play arround with something like:

I've got two base classes, _Tag and _ContainerTag (for tags which can
nest tags). Instead of getting an htmltag with _Tag(name='html'), I
want to have a class for each html-tag. So, I thought of creating that
classes dynamicly.

my now (nearly) working code is:

class _Tag(object):
def __init__(self, name, flags=None, **props):
[...]

class _ContainerTag(_Tag):
def __init__(self, name, contents=None, flags=None, **props):
super(_ContainerTag, self).__init__(name=name, flags=flags, 
**props)
self._contents = coalesce(contents, [])


_module_name = sys.modules[__name__]

class_dic = {}
class_dic['Br'] = _Tag
class_dic['Hr'] = _Tag
class_dic['Html'] = _ContainerTag
class_dic['Table'] = _ContainerTag

for class_name, class_base in class_dic.items():
class TmpClass(class_base):
def __init__(self, **props):
name = class_name.lower()
#super(TmpClass, self).__init__(name=name, **props)
class_base.__init__(self, name=name, **props)
setattr(_module_name, class_name, TmpClass)

br = Br()
print br
table = Table()
print table

br is printed OK, but for table, I get:
AttributeError: 'TmpClass' object has no attribute '_contents'
so, it seems that __init__ of _Tag is not called. 
If I try to do the commented line
super(TmpClass, self).__init__(name=name, **props)
instead of
class_base.__init__(self, name=name, **props)
I get:
 TypeError: super(type, obj): obj must be an instance or subtype of
 type
for print table, print br ist processed OK.


Thanks for help and your perfekt examples,
AXEL.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Generating modul classes with eval

2005-02-03 Thread Peter Otten
Axel Straschil wrote:

 class_dic = {}
 class_dic['Br'] = _Tag
 class_dic['Hr'] = _Tag
 class_dic['Html'] = _ContainerTag
 class_dic['Table'] = _ContainerTag
 
 for class_name, class_base in class_dic.items():
 class TmpClass(class_base):
 def __init__(self, **props):
 name = class_name.lower()
 #super(TmpClass, self).__init__(name=name, **props)
 class_base.__init__(self, name=name, **props)
 setattr(_module_name, class_name, TmpClass)

While your workaround doesn't balk immediately, it doesn't do the right
thing either.

After the loop has finished, the global variable TmpClass will be bound to
whatever class was created last, and the variable class_base will be bound
to that the base class of that same TmpClass. Therefore only this last class
is guaranteed to work as expected.

A simplified example to demonstrate the binding problem:

 classes = []
 for text in [alpha, beta]:
... class T:
... def __init__(self): print text
... classes.append(T)
...
 classes[0] is classes[1]
False # two distinct classes, as expected
 classes[0]()
beta
__main__.T instance at 0x402a9e2c
 classes[1]()
beta
__main__.T instance at 0x402a9f8c

And now the proof that you are actually accessing the global variable: 

 text = gamma
 classes[0]()
gamma
__main__.T instance at 0x402a9f8c

One way to fix this is to introduce a factory function:

 def make_class(text):
... class T:
... def __init__(self): print text
... return T
...
 classes = []
 for text in [alpha, beta]:
... classes.append(make_class(text))
...
 classes[0]()
alpha
__main__.T instance at 0x402a9e4c
 classes[1]()
beta
__main__.T instance at 0x402a9f8c



Peter

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Generating modul classes with eval

2005-02-03 Thread Axel Straschil
Hello!

 After the loop has finished, the global variable TmpClass will be bound to
 whatever class was created last, and the variable class_base will be bound
 to that the base class of that same TmpClass. Therefore only this last class
 is guaranteed to work as expected.

Great, now it workes!

_module_name = sys.modules[__name__]
def _tag_class_factory(name, base):
class T(base):
def __init__(self, **props):
super(T, self).__init__(name=name.lower(), **props)
setattr(_module_name, name, T)
class_dic = {}
class_dic['Br'] = _Tag
class_dic['Hr'] = _Tag
class_dic['Html'] = _ContainerTag
class_dic['Table'] = _ContainerTag
class_dic['Td'] = _ContainerTag
class_dic['Tr'] = _ContainerTag
for name, base in class_dic.items():
_tag_class_factory(name, base)
print Table(contents=[Tr(contents=[Br()])])

gives: tabletrbr//tr/table

Thanks,
AXEL.

-- 
http://mail.python.org/mailman/listinfo/python-list


Generating modul classes with eval

2005-02-02 Thread Axel Straschil
Hello!

I was fooling around with creating classes for a module with eval,
something like:

MyModule.py:

class Base:
init(self, name):
self._name = name

for myclass in ['A', 'B', 'C']:
code=class %s(Base):\n\tinit(self, name='%s')\n\t\tsuper(%s,
self).__init(name=name)\n%dict(myclass, myclass.lower(), myclass())
... codeop and eval stuff ...
a=A()
print a

that gives: class '__main__.A', but I want MyModule.A ;-)

Can someone give me a hint how to create classes in a module with eval
and codeop so that they exist like the code was written in?

Thanks, 
AXEL.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Generating modul classes with eval

2005-02-02 Thread Steve Holden
Axel Straschil wrote:
Hello!
I was fooling around with creating classes for a module with eval,
something like:
MyModule.py:
class Base:
init(self, name):
self._name = name
for myclass in ['A', 'B', 'C']:
code=class %s(Base):\n\tinit(self, name='%s')\n\t\tsuper(%s,
self).__init(name=name)\n%dict(myclass, myclass.lower(), myclass())
... codeop and eval stuff ...
a=A()
print a
that gives: class '__main__.A', but I want MyModule.A ;-)
Can someone give me a hint how to create classes in a module with eval
and codeop so that they exist like the code was written in?
Thanks, 
AXEL.

You could try just importing the module - then, when it runs, its name 
won't be __main__ but MyModule.

regards
 Steve
--
Meet the Python developers and your c.l.py favorites March 23-25
Come to PyCon DC 2005  http://www.python.org/pycon/2005/
Steve Holden   http://www.holdenweb.com/
--
http://mail.python.org/mailman/listinfo/python-list


Re: Generating modul classes with eval

2005-02-02 Thread Jeremy Bowers
On Wed, 02 Feb 2005 16:20:41 -0500, Jeremy Bowers wrote:
 That said, __main__ indicates you ran it in the interactive shell.

Or ran it directly on the command line. Duh. I thought that clause really
loudly, but I guess I never actually typed it.
-- 
http://mail.python.org/mailman/listinfo/python-list