[Python-3000] Class Decorators + ctypes (Was: yes to class decorators)

Talin talin at acm.org
Thu Nov 16 06:41:43 CET 2006


tomer filiba wrote:
> here are some usecases to class decorators:

What I would like is a way to use class decorators, combined with 
ctypes, to effectively 'declare' a C structure using Python syntax. 
Right now you can use ctypes to declare a C struct, but the syntax isn't 
very Python-like:

    class RECT(Structure):
      _fields_ = [("upperleft", POINT),
                  ("lowerright", POINT)]

Even with class decorators, however, there is still a missing piece - 
there's no way to decorate a variable declaration. That's because 
there's no equivalent of 'def' for variables. (Thinking about it, it 
does seem like there's an asymmetry here - you can define functions 
using 'def' or using assignment, but you can define variables only using 
assignment.)

Here's a more specific proposal: The token '->' has been proposed (as 
part of the argument decorator syntax) as a way to indicate the return 
type of a function definition. What if a similar syntax could be used to 
  define and create a class variable?

Here's an example. I realize that the syntax may look strange, but it's 
all a logical extension of things that have already been proposed and 
for the most part accepted:

@cstruct
class CPoint:

    def x -> float
    def y -> float

Under the hood, here's what's happening:

1) 'def' without an argument list defines a variable instead of a function.

2) The '-> float' is merely advisory - it has no meaning except to the 
decorator, just as has been proposed with argument decorators.

3) The @cstruct decorator changes the way that the class is evaluated, 
adding an implicit decorator to each definition. In this case, it 
evaluates the argument decorators and adds a field definition for each one.

One unresolved issue is what exactly gets assigned to 'x' and 'y' at the 
time the class definition is evaluated. Ordinarily, 'def' adds a named 
entry to the class dict. In a normal function declaration, the part 
after the colon defines a suite, which is the value assigned to the name.

I first thought about allowing the same colon to be used to define the 
value to assign to the variable, i.e.:

    def x -> float: 0

However, this is inconsistent with the use of the colon in other places 
in Python, which generally introduces a suite.

An alternative would be to use an assignment operator:

    def x -> float = 0

The only difference between this and simply 'x = 0' is that the 'def' 
statement, unlike an assignment, can be decorated.

A different approach would be to say that the class decorator can 
overload the '__setattr__' method on the class itself during class creation:

@cstruct
class CPoint:

    x = FLOAT
    y = FLOAT

I think that you would *only* want to do this override during the 
initial evaluation of the class. Once the class was fully created, I 
would think that you'd want to be able to do "CPoint.x = value" without 
triggering the decorator's override.

(As a bit of trivia that may be of interest: The latest proposals for 
extending the C++ language allow a function return type to be declared 
using the "(args) -> returntype" syntax. The primary reason for doing 
this is to avoid certain syntactical ambiguities and to allow support 
for lambda functions in C++, but there are some other advantages to 
doing so when using functions as template arguments.)

-- Talin



More information about the Python-3000 mailing list