<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
There's a whole matrix of these and I'm wondering why the matrix is
currently sparse rather than implementing them all. Or rather, why
we can't stack them as:<br>
<br>
<tt>class foo(object):<br>
@classmethod<br>
@property<br>
def bar(cls, ...):<br>
...</tt><br>
<br>
Essentially the permutation are, I think:
{'unadorned'|abc.abstract}{'normal'|static|class}{method|property|non-callable
attribute}.<br>
<br>
<table border="1" cellpadding="2" cellspacing="2" width="100%">
<tbody>
<tr>
<th valign="top">concreteness<br>
</th>
<th valign="top">implicit first arg<br>
</th>
<th valign="top">type<br>
</th>
<th valign="top">name<br>
</th>
<th valign="top">comments<br>
</th>
</tr>
<tr>
<td valign="top">{unadorned}<br>
</td>
<td valign="top">{unadorned}<br>
</td>
<td valign="top">method<br>
</td>
<td valign="top">def foo():<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">{unadorned}</td>
<td valign="top">property<br>
</td>
<td valign="top">@property<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">{unadorned}</td>
<td valign="top">non-callable attribute<br>
</td>
<td valign="top">x = 2<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">static<br>
</td>
<td valign="top">method</td>
<td valign="top">@staticmethod<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">static</td>
<td valign="top">property</td>
<td valign="top">@staticproperty<br>
</td>
<td valign="top">proposing<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">static</td>
<td valign="top">non-callable attribute</td>
<td valign="top">{degenerate case - variables don't have
arguments}<br>
</td>
<td valign="top">unnecessary<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">class<br>
</td>
<td valign="top">method</td>
<td valign="top">@classmethod<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">class</td>
<td valign="top">property</td>
<td valign="top">@classproperty or @classmethod;@property<br>
</td>
<td valign="top">proposing<br>
</td>
</tr>
<tr>
<td valign="top">{unadorned}</td>
<td valign="top">class</td>
<td valign="top">non-callable attribute</td>
<td valign="top">{degenerate case - variables don't have
arguments}<br>
</td>
<td valign="top">unnecessary</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">{unadorned}</td>
<td valign="top">method</td>
<td valign="top">@abc.abstractmethod<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">{unadorned}</td>
<td valign="top">property</td>
<td valign="top">@abc.abstractproperty<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">{unadorned}</td>
<td valign="top">non-callable attribute</td>
<td valign="top">@abc.abstractattribute or
@abc.abstract;@attribute<br>
</td>
<td valign="top">proposing<br>
</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">static</td>
<td valign="top">method</td>
<td valign="top">@abc.abstractstaticmethod<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">static</td>
<td valign="top">property</td>
<td valign="top">@abc.staticproperty<br>
</td>
<td valign="top">proposing</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">static</td>
<td valign="top">non-callable attribute</td>
<td valign="top">{degenerate case - variables don't have
arguments}</td>
<td valign="top">unnecessary</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">class</td>
<td valign="top">method</td>
<td valign="top">@abc.abstractclassmethod<br>
</td>
<td valign="top">exists now<br>
</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">class</td>
<td valign="top">property</td>
<td valign="top">@abc.abstractclassproperty<br>
</td>
<td valign="top">proposing<br>
</td>
</tr>
<tr>
<td valign="top">abc.abstract</td>
<td valign="top">class</td>
<td valign="top">non-callable attribute</td>
<td valign="top">{degenerate case - variables don't have
arguments}</td>
<td valign="top">unnecessary</td>
</tr>
</tbody>
</table>
<br>
I think the meanings of the new ones are pretty straightforward, but
in case they are not...<br>
<br>
@staticproperty - like @property only without an implicit first
argument. Allows the property to be called directly from the class
without requiring a throw-away instance.<br>
<br>
@classproperty - like @property, only the implicit first argument to
the method is the class. Allows the property to be called directly
from the class without requiring a throw-away instance.<br>
<br>
@abc.abstractattribute - a simple, non-callable variable that must
be overridden in subclasses<br>
<br>
@abc.abstractstaticproperty - like @abc.abstractproperty only for
@staticproperty<br>
<br>
@abc.abstractclassproperty - like @abc.abstractproperty only for
@classproperty<br>
<br>
--rich<br>
<br>
<br>
</body>
</html>