Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing static fields from the decorated class

Full code example:

def decorator(class_):
    class Wrapper:
        def __init__(self, *args, **kwargs):
            self.instance = class_(*args, **kwargs)

        @classmethod
        def __getattr__(cls, attr):
            return getattr(class_, attr)
    return Wrapper


@decorator
class ClassTest:

    static_var = "some value"


class TestSomething:

    def test_decorator(self):
        print(ClassTest.static_var)
        assert True

When trying to execute test, getting error:

test/test_Framework.py F
test/test_Framework.py:37 (TestSomething.test_decorator)
self = <test_Framework.TestSomething object at 0x10ce3ceb8>

    def test_decorator(self):
>       print(ClassTest.static_var)
E       AttributeError: type object 'Wrapper' has no attribute 'static_var'

Is it possible to access static fields from the decorated class?

like image 518
Oleh Kuzovkov Avatar asked Dec 19 '17 16:12

Oleh Kuzovkov


People also ask

What is a static attribute in Python?

Static means, that the member is on a class level rather on the instance level. Static variables exist only on class level and aren't instantiated. If you change a static variable in one instance of the class, the change will affect its value in all other instances.

What is a static class in Python?

Static methods in Python are extremely similar to python class level methods, the difference being that a static method is bound to a class rather than the objects for that class. This means that a static method can be called without an object for that class.

Can static method be accessed by object Python?

Unlike instance methods, static methods aren't bound to an object. In other words, static methods cannot access and modify an object state. In addition, Python doesn't implicitly pass the cls parameter (or the self parameter) to static methods.

Can class methods use self?

Class methods don't need a class instance. They can't access the instance ( self ) but they have access to the class itself via cls . Static methods don't have access to cls or self . They work like regular functions but belong to the class's namespace.


1 Answers

While the answer from @martineau probably better addresses the specific issue you are trying to solve, the more general approach might be to use create a metaclass in order to redefine the instance method __getattr__ on a type instance (and classes are instances of type).

def decorator(class_):
    class WrapperMeta(type):
        def __getattr__(self, attr):
            return getattr(class_, attr)

    class Wrapper(metaclass=WrapperMeta):
        def __init__(self, *args, **kwargs):
            self.instance = class_(*args, **kwargs)

    return Wrapper

This allows the attribute look-up on the class itself to be passed through WrapperMeta.__getattr__.

like image 58
Jared Goguen Avatar answered Nov 15 '22 08:11

Jared Goguen