Re: Mix-In Class Methods At Run-Time
Bruno Desthuilliers wrote: > [EMAIL PROTECTED] wrote: > > Bruno Desthuilliers wrote: > > > >>[EMAIL PROTECTED] wrote: > (snip) > > >>>and 2) what's the reason to use newstyle classes > >>>versus the old? > >> > >>All this is explained on python.org (there's a menu entry for this in > >>the documentation menu). AFAICT, newstyle classes can do whatever > >>oldstyle classes did, *and much more* (descriptors and usable > >>metaclasses) - and they are somewhat faster too. So - compatibility with > >>older Python versions (< 2.2 IIRC) set aside -, there's just no reason > >>to use oldstyle classes. > >> > >> > >>> In order to create the dynamic class "NewClass" in the > >>>code above I called type() but that requires at least one new style > >>>class as a base. Thus, I had to have at least one of my animals inherit > >>>from "object" and this seemed a nuisance since > >> > >>OMG, eight more keystrokes - talk about a nuisance... > > > > > > Like, Oh My God! *claps hand to mouth* lol You humor me. Yes, eight > > more keystrokes. I follow the general rule of, if I'm going to put in > > extra effort, > > OMG, eight more keystrokes - talk about extra effort !-) As I said, its not the effort, its the personal need to know why the effort, however small, is being put in. > > > I'd like to know why. > > The only reason for *not* doing it would be compat issues with pre 2.2.x > versions. > > > So you see, it's not so much an > > adversion to the eight keystrokes (multiplied by however many classes I > > have mind you), > > Strange enough, I do write my share of Python code, and don't even > notice typing the EightKeystrokes. > > > but to not knowing why I should use them. > > Because they are kind of the standard Python object model since 2.2.x ?-) What kind of answer is that? What does that actually mean to me? I'm talking practical reasons here > > Did you at least take time to read the doc on newstyle classes on > python.org ? > > FWIW, with 2.5, even exceptions are now newstyle classes. No more > oldstyle classes in the builtins. And AFAICT, no more oldstyle classes > in the standard lib neither. Does that ring a bell ? Yes yes, but I've been able to use all that without declaring a single new-style class. So my question was, what penalty do I actually pay... > > > If I don't > > care for descriptors or metaclasses, > > You *do* care for descriptors. Without descriptors, no properties, no > classmethods, no staticmethods... What a desolation :( > > More seriously, given what you're into actually, not caring about what > one can do with newstyle classes seems really strange to me - like > digging a swimming-pool with a pick and a shovel when you have an > excavator... (disclaimer : google translation, not sure it makes sens in > english...) You have it backwards. Of course I care what can be done with new-style classes. That was precisely the basis for my original question. I wanted to know what those eight keystrokes * #ofclasses gets me, and if its necessary versus just a key to unlock features that I may or may not need. -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
[EMAIL PROTECTED] wrote: > Bruno Desthuilliers wrote: > >>[EMAIL PROTECTED] wrote: (snip) >>>and 2) what's the reason to use newstyle classes >>>versus the old? >> >>All this is explained on python.org (there's a menu entry for this in >>the documentation menu). AFAICT, newstyle classes can do whatever >>oldstyle classes did, *and much more* (descriptors and usable >>metaclasses) - and they are somewhat faster too. So - compatibility with >>older Python versions (< 2.2 IIRC) set aside -, there's just no reason >>to use oldstyle classes. >> >> >>> In order to create the dynamic class "NewClass" in the >>>code above I called type() but that requires at least one new style >>>class as a base. Thus, I had to have at least one of my animals inherit >>>from "object" and this seemed a nuisance since >> >>OMG, eight more keystrokes - talk about a nuisance... > > > Like, Oh My God! *claps hand to mouth* lol You humor me. Yes, eight > more keystrokes. I follow the general rule of, if I'm going to put in > extra effort, OMG, eight more keystrokes - talk about extra effort !-) > I'd like to know why. The only reason for *not* doing it would be compat issues with pre 2.2.x versions. > So you see, it's not so much an > adversion to the eight keystrokes (multiplied by however many classes I > have mind you), Strange enough, I do write my share of Python code, and don't even notice typing the EightKeystrokes. > but to not knowing why I should use them. Because they are kind of the standard Python object model since 2.2.x ?-) Did you at least take time to read the doc on newstyle classes on python.org ? FWIW, with 2.5, even exceptions are now newstyle classes. No more oldstyle classes in the builtins. And AFAICT, no more oldstyle classes in the standard lib neither. Does that ring a bell ? > If I don't > care for descriptors or metaclasses, You *do* care for descriptors. Without descriptors, no properties, no classmethods, no staticmethods... What a desolation :( More seriously, given what you're into actually, not caring about what one can do with newstyle classes seems really strange to me - like digging a swimming-pool with a pick and a shovel when you have an excavator... (disclaimer : google translation, not sure it makes sens in english...) > I don't see why I should feel > compelled to use them. "them" -> "newstyle classes" or "descriptors and metaclasses" ? > And when I decide I want/need these features, I > can put the eight keystroke in at that time. What can I say ? That's your code, not mine... -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
Bruno Desthuilliers wrote: > [EMAIL PROTECTED] wrote: > (snip) > > > Two additional questions though: 1) is there a way for a function to > > get a reference to its caller automatically (as in, without the caller > > having to pass it in)? > > It's possible with sys._getframe() and a decorator - but consider it a > hack. Gotcha, thanks. > > > and 2) what's the reason to use newstyle classes > > versus the old? > > All this is explained on python.org (there's a menu entry for this in > the documentation menu). AFAICT, newstyle classes can do whatever > oldstyle classes did, *and much more* (descriptors and usable > metaclasses) - and they are somewhat faster too. So - compatibility with > older Python versions (< 2.2 IIRC) set aside -, there's just no reason > to use oldstyle classes. > > > In order to create the dynamic class "NewClass" in the > > code above I called type() but that requires at least one new style > > class as a base. Thus, I had to have at least one of my animals inherit > > from "object" and this seemed a nuisance since > > OMG, eight more keystrokes - talk about a nuisance... Like, Oh My God! *claps hand to mouth* lol You humor me. Yes, eight more keystrokes. I follow the general rule of, if I'm going to put in extra effort, I'd like to know why. So you see, it's not so much an adversion to the eight keystrokes (multiplied by however many classes I have mind you), but to not knowing why I should use them. If I don't care for descriptors or metaclasses, I don't see why I should feel compelled to use them. And when I decide I want/need these features, I can put the eight keystroke in at that time. No biggy. :-) Thanks Bruno. > > > I don't at this point > > know what the benefit of "newstyle" classes is. > > See it the other way round : the *only* benefit of oldstyle classes is > compatibility with pre-2.2 Python versions. > > -- > bruno desthuilliers > python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for > p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
I can't give much answers, I am not that expert yet. Bruno Desthuilliers: > newstyle classes can do whatever oldstyle classes > did, *and much more* (descriptors and usable > metaclasses) - and they are somewhat faster too. In the past I have done few tests, and it seemed that new style classes are a bit slower (but the difference doesn't make much difference). Maybe for Py2.5 the situation will be different. Bye, bearophile -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
[EMAIL PROTECTED] wrote: (snip) > Two additional questions though: 1) is there a way for a function to > get a reference to its caller automatically (as in, without the caller > having to pass it in)? It's possible with sys._getframe() and a decorator - but consider it a hack. > and 2) what's the reason to use newstyle classes > versus the old? All this is explained on python.org (there's a menu entry for this in the documentation menu). AFAICT, newstyle classes can do whatever oldstyle classes did, *and much more* (descriptors and usable metaclasses) - and they are somewhat faster too. So - compatibility with older Python versions (< 2.2 IIRC) set aside -, there's just no reason to use oldstyle classes. > In order to create the dynamic class "NewClass" in the > code above I called type() but that requires at least one new style > class as a base. Thus, I had to have at least one of my animals inherit > from "object" and this seemed a nuisance since OMG, eight more keystrokes - talk about a nuisance... > I don't at this point > know what the benefit of "newstyle" classes is. See it the other way round : the *only* benefit of oldstyle classes is compatibility with pre-2.2 Python versions. -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
Okay, while I'd still like to know the answer(s) to my earlier question(s), I've mostly solved my problem thanks to bearophile and my own learning. An example: class Cat(object): def __init__(self): self.love = 0 def meow(self): print "meow" class Dog(object): def bark(self): print "bark" class Bat(object): def scream(self): print "scream" def Mixin(object, *classes): NewClass = type('Mixin', (object.__class__,) + classes, {}) newobj = NewClass() newobj.__dict__.update(object.__dict__) return newobj mycat = Cat() mycat.love = 4 mycat = Mixin(mycat, Dog, Bat) print mycat.__dict__, mycat.__class__, mycat.__class__.__bases__ print dir(mycat) Two additional questions though: 1) is there a way for a function to get a reference to its caller automatically (as in, without the caller having to pass it in)? and 2) what's the reason to use newstyle classes versus the old? In order to create the dynamic class "NewClass" in the code above I called type() but that requires at least one new style class as a base. Thus, I had to have at least one of my animals inherit from "object" and this seemed a nuisance since I don't at this point know what the benefit of "newstyle" classes is. I was going to just use the new module and classobj() but I read somewhere that that was unadvisable and newstyle classes should be used in new code. ... Thank you. Cheers, DigiO [EMAIL PROTECTED] wrote: > This looks excellent bearophile, but I'm having trouble understanding > some things. Perhaps you can help wipe clean my ignorance. Firstly, I > thought __classes__ was a read-only attribute? Secondly, what is a > "dictproxy object" and why won't the following code work: > > class Cat: > def meow(self): > print "meow" > def MixIn(object, *classes): > temp = type('ClassPie', (object.__class__,) + classes, {}) > temp.__dict__.update([object.__dict__]) > NewClass = MixIn(Cat(), C, D) > test = NewClass() > > __dict__, to my understanding, is suppose to be a dictionary, but > Python keeps telling me it's a 'dictproxy' object and that it has no > attribute 'update'. Why is this? > > Thanks. > > > [EMAIL PROTECTED] wrote: > > I think it's possible, most of such kind of things are possible with > > Python. > > I'm not an expert yet in such kind of things, so this can be a starting > > point for you (note the shadowing of m2, the class docstrings, etc). > > Other people can give you something better or more correct. > > > > class A: > > def m1(self): return "m1" > > def m2(self): return "m2" > > > > class B: > > def m3(self): return "m3" > > > > class P: > > def m2(self): return "m2b" > > def m4(self): return"m4" > > > > def mixin(object, *classes): > > class NewClass(object.__class__): > > pass > > for C in classes: > > NewClass.__dict__.update(C.__dict__) > > object.__class__ = NewClass > > > > foo = P() > > print "Before:" > > print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys() > > print "P.__dict__.keys():", P.__dict__.keys() > > print "foo.m2():", foo.m2() > > print "foo.m4():", foo.m4(), "\n" > > > > mixin(foo, A, B) > > > > print "After:" > > print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys() > > print "P.__dict__.keys():", P.__dict__.keys() > > print "foo.m1():", foo.m1() > > print "foo.m2():", foo.m2() > > print "foo.m3():", foo.m3() > > print "foo.m4():", foo.m4() > > > > Bye, > > bearophile -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
This looks excellent bearophile, but I'm having trouble understanding some things. Perhaps you can help wipe clean my ignorance. Firstly, I thought __classes__ was a read-only attribute? Secondly, what is a "dictproxy object" and why won't the following code work: class Cat: def meow(self): print "meow" def MixIn(object, *classes): temp = type('ClassPie', (object.__class__,) + classes, {}) temp.__dict__.update([object.__dict__]) NewClass = MixIn(Cat(), C, D) test = NewClass() __dict__, to my understanding, is suppose to be a dictionary, but Python keeps telling me it's a 'dictproxy' object and that it has no attribute 'update'. Why is this? Thanks. [EMAIL PROTECTED] wrote: > I think it's possible, most of such kind of things are possible with > Python. > I'm not an expert yet in such kind of things, so this can be a starting > point for you (note the shadowing of m2, the class docstrings, etc). > Other people can give you something better or more correct. > > class A: > def m1(self): return "m1" > def m2(self): return "m2" > > class B: > def m3(self): return "m3" > > class P: > def m2(self): return "m2b" > def m4(self): return"m4" > > def mixin(object, *classes): > class NewClass(object.__class__): > pass > for C in classes: > NewClass.__dict__.update(C.__dict__) > object.__class__ = NewClass > > foo = P() > print "Before:" > print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys() > print "P.__dict__.keys():", P.__dict__.keys() > print "foo.m2():", foo.m2() > print "foo.m4():", foo.m4(), "\n" > > mixin(foo, A, B) > > print "After:" > print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys() > print "P.__dict__.keys():", P.__dict__.keys() > print "foo.m1():", foo.m1() > print "foo.m2():", foo.m2() > print "foo.m3():", foo.m3() > print "foo.m4():", foo.m4() > > Bye, > bearophile -- http://mail.python.org/mailman/listinfo/python-list
Re: Mix-In Class Methods At Run-Time
I think it's possible, most of such kind of things are possible with Python. I'm not an expert yet in such kind of things, so this can be a starting point for you (note the shadowing of m2, the class docstrings, etc). Other people can give you something better or more correct. class A: def m1(self): return "m1" def m2(self): return "m2" class B: def m3(self): return "m3" class P: def m2(self): return "m2b" def m4(self): return"m4" def mixin(object, *classes): class NewClass(object.__class__): pass for C in classes: NewClass.__dict__.update(C.__dict__) object.__class__ = NewClass foo = P() print "Before:" print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys() print "P.__dict__.keys():", P.__dict__.keys() print "foo.m2():", foo.m2() print "foo.m4():", foo.m4(), "\n" mixin(foo, A, B) print "After:" print "foo.__class__.__dict__.keys():", foo.__class__.__dict__.keys() print "P.__dict__.keys():", P.__dict__.keys() print "foo.m1():", foo.m1() print "foo.m2():", foo.m2() print "foo.m3():", foo.m3() print "foo.m4():", foo.m4() Bye, bearophile -- http://mail.python.org/mailman/listinfo/python-list