Python-dev'ers, Pardon the intrusion, but Aahz Maruch suggested that I post this to the python-dev list. The message below illustrates "yet another class method recipe" that Costas synthesized (and which I then modified very slightly) from various posts following another discussion on python-list about class methods (as we all await the "type/class healing" stuff some of you are working on -- go team!). This variant uses explicit "metaclasses" (defined as regular classes) whose instances ("meta objects") point to class objects (since they cannot *be* class objects in current Python). Anyway, I think the approach has some nice properties. Best regards, Jim ----- Forwarded by James Althoff/AMER/i2Tech on 05/18/01 11:23 AM ----- James Althoff To: python-list@python.org 05/14/01 02:09 cc: PM Subject: Re: Simulating Class (was Re: Does Python have Class methods)(Document link: James Althoff) Costas writes: >Ok, so after looking thru how Python works and comments from people, I >came up with what I believe may be the best way to implement Class >methods and Class variables. > ><snip> > >Costas I think this idea is quite good. I would amend it very slightly by suggesting the convention of defining *three* separate names in the enclosing module: 1) the name of the enclosing class 2) the name of the singleton instance of the enclosing class 3) the name of the enclosed class To support this, I would propose using a naming convention as below. If one is interested in defining a class Spam, then use the following names: 1) SpamMetaClass -- names the enclosing class 2) SpamMeta -- names a singleton instance of the enclosing class 3) Spam -- names the enclosed class Use the name SpamMetaClass when you need to derive a subclass of SpamMetaClass, e.g., class SpecialSpamMetaClass(SpamMetaClass): pass Use the name SpamMeta to invoke a class method, e.g., SpamMeta.aClassMethod() Use the name Spam to make instances as usual, e.g., s = Spam() (and to derive a subclass of Spam). Although SpamMetaClass is not a metaclass in the sense of Smalltalk or Ruby -- that is to say, the class Spam is not an instance of SpamMetaClass -- nonetheless, SpamMetaClass still acts as a "higher level" class that provides methods on behalf of the class Spam where said methods are 1) independent of any particular instance of Spam and 2) allow for factory-method-style creation of Spam instances -- these being two very important attributes of the metaclass concept. Plus "meta" is a nice, short name. :-) Plus using "MetaClass" to refer to the class and "Meta" to refer to the singleton instance of "MetaClass" is reasonably clear and succinct, I think. One nice thing about the proposed recipe is that the SpamMeta object is a real class instance of a real class. This means that -- unlike when using the "module function" recipe -- we get inheritance of methods, and -- unlike when using the "callable wrapper class" recipe -- we also get override of methods. The example below illustrates both of these important capabilities. class Class1MetaClass: # Base metaclass # Define "class methods" for Class1 def whoami(self): print 'Class1MetaClass.whoami:', self def new(self): # Factory method """Return a new instance""" return self.Class1() def newList(self,n=3): # Another factory method """Return a list of new instances""" l = [] for i in range(n): newInstance = self.new() l.append(newInstance) return l # Define Class1 & its "instance methods" class Class1: # Base class def whoami(self): print 'Class1.whoami:', self Class1Meta = Class1MetaClass() # Make & name the singleton metaclass instance Class1 = Class1Meta.Class1 # Make the Class1 name accessible class Class2MetaClass(Class1MetaClass): # Derived metaclass # Define "class methods" for Class2 -- Override Class1 "class methods" def whoami(self): print 'Class2MetaClass.whoami:', self def new(self): # Override the factory method return self.Class2() # Define Class2 & its "instance methods" class Class2(Class1): # Derived class def whoami(self): print 'Class2.whoami:', self Class2Meta = Class2MetaClass() # Make & name the singleton metaclass instance Class2 = Class2Meta.Class2 # Make the Class2 name accessible # Test Class1Meta.whoami() # invoke "class method" of base class Class2Meta.whoami() # invoke "class method" of derived class Class1().whoami() # make an instance & invoke "instance method" Class2().whoami() print Class1Meta.newList() # factory method print Class2Meta.newList() # inherit factory method with override >>> reload(meta6) Class1MetaClass.whoami: <meta6.Class1MetaClass instance at 00810DBC> Class2MetaClass.whoami: <meta6.Class2MetaClass instance at 00812D6C> Class1.whoami: <meta6.Class1 instance at 0081058C> Class2.whoami: <meta6.Class2 instance at 0081058C> [<meta6.Class1 instance at 0081147C>, <meta6.Class1 instance at 0081151C>, <meta6.Class1 instance at 0081009C>] [<meta6.Class2 instance at 0081147C>, <meta6.Class2 instance at 00810CCC>, <meta6.Class2 instance at 0081009C>] <module 'meta6' from 'c:\_dev\python20\meta6.py'> Jim
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4