[Types-sig] Static Methods instead of Interface construct?
Clark C. Evans
cce@clarkevans.com
Thu, 22 Mar 2001 06:26:42 -0500 (EST)
Ok... this is a bit off-the-wall, but here goes, please
excuse the semi-PEP format, but I find the structure
helpful for fleshing things out (kinda interesting how
a bit of structure helps you along, no?)
Clark
...
Abstract
So far static methods[0] do not exist in Python
This proposal asks that None be allowed when calling a
method using the class syntax, e.g., the following
syntax would be allowed, MyClass.method(None,...). Of
course, it will be no longer guaranteed that a "self"
references within a method is an instance, however, with
this additional flexibility comes power.
Motivation
Recently in the type special interest group, there have
been two proposals to introduce an Interface type. One
of those proposals introduces a completely new syntax[1]
and semantics, while the other proposal [2] only uses a
this new data type to create interfaces classes with a
single static method, __check__. While this proposal would
not help the first Interface proposal, the second interface
proposal could be implemented as an additional static
method on *existing* classes rather than introducing a
completely new construct to Python.
Furthermore, the Protocol Checking and Adaptation proposed
PEP [3] could also make wonderful use of a static method to
enable classes to provide wrappers (compliant with that class)
for specific object instances of other classes and/or types.
This is detailed in the example section.
Overall, static methods have very specific uses in the
factory pattern and the singleton design patterns. These
patterns are a useful tool in any programmers toolbox.
Although this change may be painful internally, it wont jar
the language, and Python may be able to avoid adding new
static-method like syntax constructs such as Interface.
Specification
This is very straightforward. When an unbound method is
called from a Class, either None or an instance of the Class
may be used as the instance object. Accessing the "self"
parameter within the methods body would be allowed, however,
calls to methods or attributes would give the familiar
AttributeError.
Example Usage
In the Protocol Checking and Adaptation proposed PEP [3], it
is mentioned how it may be possible for a particular protocol
(in this example, a particular class is a protocol) to
provide an adapter for an instance of another class or signal
that the object has indeed implemented enough of the required
protocol to be substitutable for objects of that class.
Given the current restrictions on static methods, this is not
easy to do. However, if None were allowed for the first
argument, then an implementation such as the following
is possible. (you may want to read the Protocol Checking and
Adaptation proposed PEP first).
-----------------------------------------------------------------
adapter.py
-----------------------------------------------------------------
# <details snipped>
def interal_adapt(obj,protocol,can_wrap):
# the obj may have the answer, so ask it about the ident
# <details snipped>
# the protocol may have the answer, so ask it about the obj
if type(protocol) is types.ClassType:
try:
retval = protocol.__adapt__(None,obj)
if retval: return retval
except:
pass # hmm
# <remaining details snipped>
-----------------------------------------------------------------
test.py
-----------------------------------------------------------------
# <details snipped>
class EggsSpamAndHam (SpamOnly,KnightsWhoSayNi):
def ham(self,str): print "ham!" + str
def __adapt__(self,protocol,can_wrap):
if self is None:
# hmm, well protocol is now foreign object
if protocol.__class__ is HamOnly:
return protocol # yep, HamOnly can pass off...
# <details snipped>
def test():
x = HamOnly()
adapt(x,EggsSpamAndHam).ham("Yepee!")
-----------------------------------------------------------------
Example Run
-----------------------------------------------------------------
>>> import test
>>> test.test()
ham!Yepee!
Anyway, its not perfect (due to the argument name splitting
its meaning...
References and Footnotes
[0] http://www.python.org/cgi-bin/faqw.py?req=show&file=faq04.084.htp
[1] http://python.sourceforge.net/peps/pep-0245.html
[2] http://mail.python.org/pipermail/types-sig/2001-March/001223.html
[3] http://mail.python.org/pipermail/python-list/2001-March/034609.html