Python 3.2 in case that matters...
The following code shows that the "concrete class" can either implement some_method as a static method or an instance method:
import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
@abc.abstractmethod
def some_method(self): pass
class ValidConcreteClass1(SomeAbstractClass):
@staticmethod
def some_method():
print("foo!")
class ValidConcreteClass2(SomeAbstractClass):
def some_method(self):
print("foo!")
ValidConcreteClass1.some_method()
instance = ValidConcreteClass2()
instance.some_method()
My question is, can I force the implementation of some_method to be static in the inheriting class?
I noticed @abc.abstractstaticmethod and thought this was the answer but the following code still runs just fine. I would think it would reject ValidConreteClass2 because some_method is not static:
import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
@abc.abstractstaticmethod
def some_method(self): pass
class ValidConcreteClass1(SomeAbstractClass):
@staticmethod
def some_method():
print("foo!")
class ValidConcreteClass2(SomeAbstractClass):
def some_method(self):
print("foo!")
ValidConcreteClass1.some_method()
instance = ValidConcreteClass2()
instance.some_method()
Declaring abstract method static If you declare a method in a class abstract to use it, you must override this method in the subclass. But, overriding is not possible with static methods. Therefore, an abstract method cannot be static.
It's not allowed because inheritance is about creating related classes of objects, and you're not creating any objects at all with static classes.
While an abstract class cannot be instantiated, it can have implementation details. The designers of C# chose to force the user to either implement the functionality, or specifically state that the functionality inherited from the interface will not be implemented at this level.
A static method belongs to class not to object instance thus it cannot be overridden or implemented in a child class. So there is no use of making a static method as abstract.
I think some clarification is needed;
First, in Python every method is virtual - really virtual; so whether a method is static, or bound to a class or instance, that's a matter of the subclass, not of the parent one. You don't have a real reason for wanting to prevent that - what's your purpose?
Second, ABCs check for abstractness at instantiation time - if you try instancing a class that's still got any abstract method, an error will be raised. But ABCs can't do anything on static or class methods that are invoked from the class itself - there's NO CHECK performed on the method itself, just an attribute set on the method - it's ABCMeta that does the dirty work when the class is instanced.
Third, the purpose of abstractstaticmethod is to allow an abstract method - hence something that must be still be overriden someway by subclasses - to be static and used from anywhere - again, there's no check done on the method itself, so the following code is perfectly legal:
import abc
class SomeAbstractClass(metaclass=abc.ABCMeta):
@abc.abstractstaticmethod
def some_method():
return 123
class ValidConcreteClass1(SomeAbstractClass):
def some_method(self):
return 456
inst = ValidConcreteClass1()
print(inst.some_method())
print(SomeAbstractClass.some_method())
The only reason for abstractstaticmethod/abstractclassmethod existence is that the following does not work because decorated methods lack a dict
class NotWorking(metaclass=abc.ABCMeta):
@abc.abstractmethod
@staticmethod
def some_method(self):
return "asd"
One last thing: if you really wanted to, you could probably add such functionality by extending ABCMeta, but I won't give you an hook on how to do this unless you tell me why you're doing that :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With