impostazione di una proprietà in __init__

voti
-1

Voglio creare una classe figlia Bda Ae utilizzare il __init__da Aperché è identica fino a un attributo / proprietà.

Il seguente codice mostra quello che vorrei fare

class A:
    def __init__(self):
        self.a = 1
        self.b = 1
        self.c = 1

class B(A):
    def __init__(self):
        super().__init__()  # because I want 'a' and 'b', (but not 'c')

    @property
    def c(self):
        return 2

B()

Rintracciare:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-95c544214e48> in <module>()
     13         return 2
     14 
---> 15 B()

<ipython-input-9-95c544214e48> in __init__(self)
      7 class B(A):
      8     def __init__(self):
----> 9         super().__init__()  # because I want 'a' and 'b', (but not 'c')
     10 
     11     @property

<ipython-input-9-95c544214e48> in __init__(self)
      3         self.a = 1
      4         self.b = 1
----> 5         self.c = 1
      6 
      7 class B(A):

AttributeError: can't set attribute

Ho pensato che avrei potuto risolvere questo problema facendo

class B(A):
    def __init__(self):
        super().__init__()  # because I want 'a' and 'b', (but not 'c')
        self.c = property(lambda s: 2)

Tuttavia quando poi chiama:

>>> B().c
<property at 0x116f5d7c8>

la proprietà non viene valutata.

Come posso fare questo correttamente senza copiare manualmente __init__da A?

È pubblicato 26/09/2018 alle 14:35
fonte dall'utente
In altre lingue...                            


1 risposte

voti
1

Un modo per ovviare a tale è quello di trasformare cin una proprietà in Apure; la proprietà restituisce solo il membro (privato) self._c:

class A:
    def __init__(self):
        self.a = 1
        self.b = 1
        self._c = 1

    @property
    def c(self):
        return self._c

class B(A):
    def __init__(self):
        super().__init__()  # because I want 'a' and 'b', (but not 'c')
        self._c = 2

    # is already inherited from A
    # @property
    # def c(self):
    #     return self._c

a = A()
b = B()
print(a.c)  # 1
print(b.c)  # 2

se non è possibile cambiare A(e supponendo che lo scopo della vostra proprietà è quello di rendere cdi sola lettura), che è una variante: la c.settersolleverà un errore, se self._cnon è None:

class A:
    def __init__(self):
        self.a = 1
        self.b = 1
        self.c = 1

class B(A):
    def __init__(self):
        self._c = None
        super().__init__()  # the setter for c will work as self._c = None
        self._c = 2         # now we set c to the new value 
                            # (bypassing the setter)

    @property
    def c(self):
        return self._c

    @c.setter
    def c(self, value):
        if self._c is not None:
            raise AttributeError
        self._c = value
Risposto il 26/09/2018 a 14:43
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more