Creating a variable not inherited in python

Is there a way to make a variable non-inherited in python? As in the following example: B is a subclass of A, but I want it to have its own SIZE value.

Can I get an error message (on __init__ or on getsize ()) if B does not override SIZE?

class A:
   SIZE = 5
   def getsize(self): return self.SIZE

class B(A): pass

Edit : ... when inheriting the getsize () method ...?

+3
source share
8 answers

If you want to make absolutely sure that the subclasses are Aoverride SIZE, you can use the metaclass for A, which will throw an error if the subclass does not override it (note that this Ais a new-style class):

class ClassWithSize(type):
    def __init__(cls, name, bases, attrs):
        if 'SIZE' not in attrs:
            raise NotImplementedError('The "%s" class does not implement a "SIZE" attribute' % name)
        super(ClassWithSize, cls).__init__(name, bases, attrs)

class A(object):
    __metaclass__ = ClassWithSize

    SIZE = 5
    def getsize(self):
        return self.SIZE

class B(A):
    SIZE = 6

class C(A):
    pass

, , C.

+4

:

( )

, :

class A:
    SIZE = 5
    def __init__(self):
        if self.__class__ != A:
            del self.SIZE

    def getsize(self):
        return self.SIZE

class B(A):
    pass

a = A()
print a.getsize()
# Prints 5

b = B()
print b.getsize()
# AttributeError: B instance has no attribute 'SIZE'
+7

( !), - ( ), :

class A(object):

  @property
  def SIZE(self):
    if type(self) is not A:
      raise AttributeError("Class %s MUST explicitly define SIZE!" % 
                            type(self).__name__)

  def getsize(self):
    return self.SIZE

, , A, SIZE, self.SIZE ( , , A).

+2

, , hasattr(self.__class__, 'SIZE') getsize() , . - :

class A:
   SIZE = 5
   def getsize(self):
     klass = self.__class__
     if hasattr(klass, 'SIZE') and 'SIZE' in klass.__dict__:
       return self.SIZE
     raise NotImplementedError('SIZE is not defined in ' + klass.__name__)

- , SIZE getsize . , type(klass.SIZE), , .

+1

:

class B(A):  
  SIZE = 6
0

, , . , :

class A:
    __SIZE = 5
    def getsize(self): 
        return self.__SIZE

    def setsize(self,newsize):
        self.__SIZE=newsize

class B(A): 
    pass
0

, A B , :

class X:
    def getsize(self):
        return self.SIZE
class A(X):
    SIZE = 5

class B(X): pass

a = A()
print a.getsize()
# Prints 5

b = B()
print b.getsize()
# AttributeError: B instance has no attribute 'SIZE'
0

Another common idiom is to use NotImplemented . Think of it as an intermediate position between metaclass compliance and simple documentation.

class A:
   SIZE = NotImplemented

Now, if a subclass forgets to override SIZE, runtime errors will be immediate and obvious.

0
source

Source: https://habr.com/ru/post/1711767/


All Articles