codehaus


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How do I give a decorator acces to the class of a decorated function


On 5/09/19 15:30, Peter Otten wrote:
>> 2) Is it possible to make MyClass automatically a subclass of an other
>> class
>>    through the metaclass?
>>
> While you can modify `bases` before passing it on to `type` this starts to 
> get a bit messy. Maybe you need a real metaclass which unlike the registered 
> function above is shared by the subclasses...
>
> import random
>
> def register(f):
>     f.registered = True
>     return f
>
> class Foo: pass
> class Bar: pass
>
> class RegisterMeta(type):
>     def __new__(cls, name, bases, namespace):
>         namespace["my_cool_functions"] = [
>             n for n, v in namespace.items()
>             if getattr(v, "registered", False)
>         ]
>         return type.__new__(
>             cls, name,
>             bases + (random.choice([Foo, Bar]),),
>             namespace
>         )
>
> class RegisterBase(metaclass=RegisterMeta):
>     def __getitem__(self, i):
>         return self.my_cool_functions[i]
>
> class MyClass(RegisterBase):
>     @register
>     def foo(self):
>         pass
>     @register
>     def bar(self):
>         pass
>     def other(self):
>         pass
>
> print(MyClass.my_cool_functions)
> print(MyClass()[0])
> print(MyClass.my_cool_functions is RegisterBase.my_cool_functions)  # False
> print(MyClass.__bases__, RegisterBase.__bases__)
>
>
> ...or something else entirely. Can you provide some context?

Sure I am researching the possibility of writing an easy to use
lexing/parsing tool. The idea is to write your lexer/parser as
follows:

class Calculator(metaclass = ...):
    def __init__(self):
        self.names = set()
        self.table = {}

    @token(r'\d+')
    def NUMBER(self, st):
        return int(st)

    @token(r'\w+')
    def VAR(self, st):
        self.names.add(st)
        return st

    @production(r"VAR '=' NUMBER")
    def assign(self, prd):
        name = prd[0]
        val = prd[1]
        if name in self.names:
            self.table[name] = value
        else:
            raise CalcError("variable (%s) not available" % name)

calc = Calculator()
calc("a = 7")

So the token en production decorators register a regex/prodcution with
a specific method to be called in specific circumstances when parsing
a string.

So I need the lexing and parsing algorithms available to this class,
either by adding methods to the class or by making a subclass of the
class where they are implemented.

-- 
Antoon Pardon.