Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Create Abstract Static Property within Class

What I'd really like to do is something like this:

class X(metaclass=abc.ABCMeta):
    @abc.abstractAttribute # this doesn't exist
    var = [1,2]

class Y(X):
    var = X.var + [3,4]

This would force any subclasses of X to implement a static var attribute.

But there's no way to define a static attribute as abstract.

Attempting to use @abc.abstractmethod, combined with property, I can get close:

class X(metaclass=abc.ABCMeta):
    @property
    @abc.abstractmethod
    def var(self):
        return [1,2]

class Y(X):
    @property
    def var(self):
        return super().var + [3,4]

y=Y(); y.var gives [1,2,3,4] as desired.

But the goal is to create a static attribute/property, not an instance attribute/property.

When creating as a @staticmethod:

class X(metaclass=abc.ABCMeta):
    @property
    @staticmethod
    @abc.abstractmethod
    def var():
        return [1,2]

class Y(X):
    @property
    @staticmethod
    def var():
        return X.var + [3,4]

... then y=Y(); y.var gives TypeError 'staticmethod' object is not callable

If I switch the decorator order, this will resolve the staticmethod callable error:

class X(metaclass=abc.ABCMeta):
    @staticmethod
    @property
    @abc.abstractmethod
    def var():
        return [1,2]

class Y(X):
    @staticmethod
    @property
    def var():
        return X.var + [3,4]

The static method will work, but the property will not function as intended: y=Y(); y.var returns the property itself, <property at 0x2c16aa1b3b8>.

This answer is close to what's desired, but it doesn't work in this case since the base class, X, will already have a var attribute (so subclass can access via super).

How do you define a python class to have an abstract, static attribute/property?

like image 930
user2426679 Avatar asked Feb 28 '18 05:02

user2426679


People also ask

Can we use static in abstract class?

Yes, of course you can define the static method in abstract class. you can call that static method by using abstract class,or by using child class who extends the abstract class. Also you can able to call static method through child class instance/object.

Is it impossible to create a static variable in a Python class?

Yes, definitely possible to write static variables and methods in python. Static Variables : Variable declared at class level are called static variable which can be accessed directly using class name.

What is the difference between Staticmethod and Classmethod in Python?

The static method does not take any specific parameter. Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class.

What are abstract classes and abstract methods in Python?

Similarly, an abstract method is an method without an implementation. An abstract class may or may not include abstract methods. Python doesn’t directly support abstract classes. But it does offer a module that allows you to define abstract classes. To define an abstract class, you use the abc (abstract base class) module.

How to create a static method in a class in Python?

For this, we can use the @staticmethod decorator to create methods in a class static. A decorator is a special function specified before a function and takes the whole function as a parameter. Note that this method only works on versions of Python higher than 2.6. The @classmethod can make a method static to the class and not its object.

Is it possible to make an abstract method a static method?

Therefore, you can't force an implementation of your abstract method to be a regular, class or static method, and arguably you shouldn't. Starting with Python 3 (this won't work as you would expect in Python 2, see issue5867 ), it's now possible to use the @staticmethod and @classmethod decorators on top of @abstractmethod:

Is the property() decorator now correctly identified as abstract in Python?

Since Python 3.3 a bug was fixed meaning the property () decorator is now correctly identified as abstract when applied to an abstract method. Note: Order matters, you have to use @property above @abstractmethod from abc import ABC, abstractmethod class C (ABC): @property @abstractmethod def my_abstract_property (self): ...


1 Answers

If the requirement that it be a property is flexible, you could just define a static abstract method:

class X:
  @staticmethod
  @abstractmethod
  def var():
    pass

class Y(X):
  @staticmethod
  def var():
    return [1, 2]

>>> Y.var()
[1, 2]
like image 83
Ben Caine Avatar answered Nov 16 '22 02:11

Ben Caine