Prothon Prototypes vs Python Classes
Joe Mason
joe at notcharles.ca
Sat Mar 27 22:37:25 EST 2004
More information about the Python-list mailing list
Sat Mar 27 22:37:25 EST 2004
- Previous message (by thread): Prothon Prototypes vs Python Classes
- Next message (by thread): Prothon Prototypes vs Python Classes
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
In article <569c605ld1cj8fc1emolk08ete0s1prls1 at 4ax.com>, David MacQuigg wrote: > Playing with Prothon today, I am fascinated by the idea of eliminating > classes in Python. I'm trying to figure out what fundamental benefit > there is to having classes. Is all this complexity unecessary? Complexity's ok if it's in the right place - down deep in the heart of things where you only have to get it right once. If you simplify the language, it can push the complexity out to the API level where everybody has to deal with it. (However, see http://www.ai.mit.edu/docs/articles/good-news/subsection3.2.1.html for a counterargument.) Ed Suominen just posted a situation where classes and instances need to be treated separately. He has a class, "AutoText", with various subclasses (which I'll call "AutoA", "AutoB", etc. because I forget the details). He wants to notice whenever somebody creates a subclass of AutoText and add it to a list so that he can have an AutoAll function which creates just one instance of each. (Or something like that.) # all examples below will use the same AutoAll() autoall = [] def AutoAll(): "Return an instance of each 'class'" l = [] for i in autoall: l.append(i()) return l In Python, the easiest way to do this is with metaclasses, which is a really advanced topic. In Prothon, it's simple to "notice" when a subclass is created, because __init__ gets called! So you just say: # This is library code - complexity goes here AutoText = Base() with AutoText: def .__init__(): Base.__init__() autoall.append(self) # Users of the library create new subclasses AutoA = AutoText() AutoB = AutoText() with AutoB: def .__init__(someparams): # do stuff with someparams AutoText.__init__() The problem with this is that it doesn't work. In AutoAll(), when you call i() and create a new instance of AutoText, it adds it to autoall, so now you have an infinite loop as autoall keeps growing. So you need to build in some way to distinguish classes to add to autoall from ones you don't. Say, a register() method: # library code AutoText = Base() with AutoText: # __init__ no longer needed def .register(): autoall.append(self) # user code AutoA = AutoText() with AutoA: .register() AutoB = AutoText() with AutoB: def .__init__(someparams): # do stuff with someparams AutoText.__init__() .register() That's not all that bad, really - if you ignore metaclasses, the only way I can think of to do this in standard Python is the same, since you only have a hook when an object is created, not a class: # library code class AutoText(Base): def register(klass): autoall.append(klass) register = classmethod(register) AutoText.register() # user code class AutoA(AutoText): pass AutoA.register() class AutoB(AutoText): def __init__(self, someparams): # do stuff with someparams AutoText.__init__(self) AutoB.register() But with metaclasses, you can set a metaclass on AutoText which automatically registers each subclass as it's created, so that the explicit register() method can be skipped. # library code - the most complex yet class AutoRegister(type): def __init__(klass, name, bases, dict): autoall.append(klass) class AutoText(Base): __metaclass__ = AutoRegister def __init__(self, text): Base.__init__(self, tet) # user code - the simplist yet class AutoA(AutoText): pass class AutoB(AutoText): def __init__(self, someparams): AutoText.__init__(self) So here's one point where the simplification of prototypes actually ends up making the user code more complicated than the full Python version. As a user of that code, you have no reason at all to care about __metaclass__ and what it does - you just need to know that AutoAll() magically creates an instance of AutoText and all it's subclasses. If you ever need to actually look at the definition of AutoText, though, you'll see this __metaclass__ thing which is a little harder to understand. In the simpler version, the basics of the library are easier, which means if you have to debug it you'll have an easier time, but you have to keep calling register(). Which complexity is better is a matter of philosophy. (In this particular case, I think they're both pretty good tradeoffs.) This is obviously pretty specific to Python - most prototype based OO languages don't have the option of metaclasses. But someone else said that prototype-based languages "tend to grow features that mimic class-based ones", or soemthing like that. I think this is a good example. Joe
- Previous message (by thread): Prothon Prototypes vs Python Classes
- Next message (by thread): Prothon Prototypes vs Python Classes
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list