Risolto Settare attributi ad una classe con setattr Python

jr_sottomajor

Utente Bronze
2 Luglio 2017
71
3
41
Salve a tutti, stavo svolgendo questo esercizio:
decorator classe.png


Il mio codice è questo:
Python:
def classeBase(classe):
    setattr(classe, 'varC', 1000)
    setattr(classe, 'varl', 10)
    def f(self, v):
        print(v * self.varl)

    def g(x):
        print(x * classe.varC)
    setattr(classe, 'f', f)
    setattr(classe, 'g', g)
    return classe

@classeBase
class A:
    pass

#test
a=A()
a.f(12)
print(a.varC, a.varl)
print(A.varC, A.varl)
A.g(13)

Funziona correttamente, se non fosse che varC e varl sembrano essere entrambe variabili di classe poichè sia eseguendo a.varC (e quindi usando l'istanza) sia eseguendo A.varC( quindi usando la classe) viene sempre stampato il risultato..quindi quando faccio setattr, io assegno una variabile di classe a quanto ho capito?
Allora mi chiedo in che modo possa settare una variabile di istanza dall'esterno senza che questa diventi di classe.
Inoltre non ho ben capito la parte in cui dice " inoltre quando vengono create le istanze di una classe derivata queste 'nascono' con lo stesso valore di varl settato da __init__ di classe Base".. Non ho ben capito il motivo della precisazione, per cui non capisco se l'esercizio l'ho svolto correttamente oppure no.. Grazie in anticipo
 

St3ve

Utente Platinum
12 Ottobre 2011
2,111
1,444
669
Penso che non sia proprio quello che ti chiede l'esercizio. ClasseBase ti viene fornito esternamente e non lo puoi modificare, tu devi definire un decoratore che, applicato ad una classe, simuli la derivazione. Ti propongo una roba del genere
Python:
class ClasseBase:
    varC = 1000  
    def __init__(self):
        self.varl = 10
    def f(self, v):
        print(v * self.varl)
    @staticmethod
    def g(x):
        print(x * varC)

def deriveBaseClass(cls):
    return type(cls.__name__, (ClasseBase, ), dict())

@deriveBaseClass
class Foo: 
    pass
 

jr_sottomajor

Utente Bronze
2 Luglio 2017
71
3
41
Python:
def ClassBase(c):
    setattr(c, 'varC', 1000)
    def __init__(self):
        self.varl=10
    setattr(c, '__init__', __init__)

    def f(self, v):
        print(v*self.varl)
    setattr(c, 'f', f)

    def g(x):
        print(x*c.varC)

    setattr(c, 'g', staticmethod(g))

    return c

Si alla fine la soluzione corretta è questa.. anzichè fare una classe si fa un metodo in modo tale che le classi derivate non possano modificare i metodi e le variabili della classe base
 
Banner pubblicitario per Bright Data su Inforge.net azienda di vendita Proxy, Data Collector e Content Unlocker
Supporta Inforge con una donazione