Forum >> Principianti >> print variabile

Pagina: 1

class Classe:
    pippo = 5
    @staticmethod
    def Def1():
        pluto = 7
        #print pluto

print Classe.pippo
print Classe.Def1().pluto
e da molto tempo che non apro discussioni nel forum, quindi un saluto a tutti,
vorrei chiedere probabilmente una cosa banale, e per voi semplice magari:

in queste poche righe di codice ho una classe con un'attributo pippo con valore di 5
e un metodo avente (questo caso dovrebbe essere una variabile) di nome pluto = 7
la mia intenzione sarebbe capire se sia possibile richiamare dall'esterno della Classe
la cosiddetta variabile pluto del metodo Def1 come faccio nel primo print Classe.pippo
(preciso di non voler utilizzare ne istanze ne return per questo ho utilizzato @staticmethod)
ho provato con tutte le combinazioni che mi sono venute in mente ma nulla, credete sia fattibile?
grazie.
Così come hai impostato la Tua classe NON puoi ottenere pluto, perché per la classe non esiste per le regole di visibilità, devi fare si che il Tuo metodo "Def1" definisca tale variabile per la classe, quindi utilizzarla come le normali variabili di classe ... Ti faccio un esempio in una sessione IDLE :

class Classe:
    pippo = 5
    @staticmethod
    def Def1():
        Classe.pluto = 7

        
var Classe()
SyntaxError: invalid syntax
var = Classe()
var.pluto
Traceback (most recent call last):
  File "/usr/lib/python3.10/idlelib/run.py", line 578, in runcode
    exec(code, self.locals)
  File "<pyshell#11>", line 1, in <module>
AttributeError: 'Classe' object has no attribute 'pluto'
var.Def1()
var.pluto
7
Spero Ti sia utile, anche se mi chiedo come mai utilizzi un modo così poco ortodosso, le variabili di istanza non sarebbero più appropriate?

Fatti non foste a viver come bruti...
grazie per la risposta,

devi fare si che il Tuo metodo "Def1" definisca tale variabile per la classe, quindi utilizzarla come le normali variabili di classe ...

ma in pratica in questo modo, il metodo crea un nuovo attributo nella Classe?
se quanto detto sopra e' corretto, l'intento (se possibile) sarebbe di richiamare la variabile di Def1()
e non che, tramite Def1 vado a creare una variabile nella Classe per poi richiamarla all'esterno.


--- Ultima modifica di pypy pypy in data 2023-05-07 19:30:15 ---
ma in pratica in questo modo, il metodo crea un nuovo attributo nella Classe?

Si, esatto.

Riguardo :

se quanto detto sopra e' corretto, l'intento (se possibile) sarebbe di richiamare la variabile di Def1() e non che, tramite Def1 vado a creare una variabile nella Classe per poi richiamarla all'esterno.
Ti risponde direttamente il Tutorial, nel capitolo che ho messo in link dice :

Il namespace locale di una funzione viene creato al momento di chiamare la funzione e distrutto quando la funzione restituisce il suo risultato o emette un’eccezione che non viene gestita all’interno della funzione. (In realtà, «dimenticato» è un termine più appropriato per descrivere quello che accade.) Naturalmente le invocazioni ricorsive hanno ciascuna il proprio namespace.
Conseguenza, ovvia, di quanto sopra è che non si può accedere ad una variabile con scope locale alla funzione, perché esso viene distrutto (ovvero "dimenticato") non appena terminata la funzione. Il metodo di una classe essenzialmente non è diverso da una funzione, il suo namespace locale non è accessibile dall'esterno del metodo stesso, quindi le variabili locali alla funzione non sono accessibili dall'esterno, neanche dall'interno dell'oggetto stesso.

Pertanto non Ti rimane altro che definire o manipolare una proprietà di classe o di istanza perché possa essere disponibile una certa variabile manipolata da un metodo dell'oggetto stesso.

Almeno è quanto credo di sapere io, pur non essendo certo un guru di python, magari qualcuno più ferrato in materia conosce qualcosa che si avvicini a ciò che Vorresti, personalmente non credo sia possibile.




Forse, se descrivi precisamente i motivi e condizioni per le quali Ti servirebbe l'insolita metodologia che stai cercando di realizzare un risultato alternativo da Te accettabile potrebbe essere escogitato; se Ti va di parlarne ...




Fatti non foste a viver come bruti...
grazie nuzzopippo per la risposta

un motivo vero e proprio diciamo che non c'e', piu' che altro, e che mi ricordavo in altro


linguaggio (parlo di molti anni fa) che facevo una cosa simile e volevo replicarlo,

ma ripeto, da quanto dici, si vede che ricordavo male, si vede che era tutt'altro.





grazie per il link, ho letto una parte che mi interessava, ed una cosa non mi e' chiara

diciamo che non ho mai sentito in Python questa differenza detta in questi termini:

Tuttavia x.f non è la stessa cosa di MyClass.f: il primo è un oggetto-metodo, il secondo è un oggetto-funzione.
la riga sopra copiata fa riferimento a questi elementi: x=MyClass() e def f(self):

ma io in Python ho sempre sentito che metodi e funzioni sono la stessa cosa,

quindi ragionandoci sopra, si puo' trarre che i metodi sono istanze di funzioni?

Parlando di "altri linguaggi", il mio "battesimo" sulla OOP è avvenuto con java e li gli oggetti sono delle scatole chiuse, non è possibile sapere cosa c'è all'interno, confesso che la "liberalità" di python in materia mi ha, inizialmente, sconcertato.




Argomento interessante quello da Te posto, provo a dire la mia pur non essendo ben "carrozzato" teoricamente, sono solo un hobbysta che cerca, con scarso successo, di capirci qualcosa, le mie "interpretazioni" non valgono poi molto. Scusami se sarò un po' prolisso ma serve anche per fissare i miei pensieri.





Il Tuo quesito sorge dai concetti sviluppati nel tutorial nei capitoli "9.3.2 Gli Oggetti-Classe" e "9.3.3 Oggetti-Istanza", per comodità, nel proseguire su quanto io "credo" di aver capito, intenderò con il termine "classe" il codice stesso implementante una generica classe, quale "oggetto" una generica variabile creata da una istanza a detta classe.

Ora quando noi implementiamo un codice qualsiasi vi è un "qualcosa" che si interpone tra il codice e la sua esecuzione: l'interprete

In prima istanza l'interprete valuta il codice della classe implementata e lo interpreta secondo i parametri contenuti nel suo data-model, in tale stato "preparatorio" le definizioni di processi interne alla implementazione di una classe sono in effetti funzioni, prendendo, ad esempio, la MyClass definita al capitolo 9.3.2, sarà facile vedere ciò

Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
class MyClass:
    i = 12345
    def f(self):
        return 'hello world'

    
print(MyClass.f)
<function MyClass.f at 0x7f2c75a81cf0>
print(MyClass.f())
Traceback (most recent call last):
  File "/usr/lib/python3.10/idlelib/run.py", line 578, in runcode
    exec(code, self.locals)
  File "<pyshell#6>", line 1, in <module>
TypeError: MyClass.f() missing 1 required positional argument: 'self'
Come possiamo vedere dall'output MyClass.f è a tutti gli effetti una funzione e viene riconosciuta come tale MA non può essere utilizzata per come è stata definita ... guarda caso, definendo un oggetto "x" dalla istanza di tale classe

x = MyClass()
print(x.f)
<bound method MyClass.f of <__main__.MyClass object at 0x7f2c75a4b700>>
print(x.f())
hello world
x.f() viene eseguito MA non è più una funzione bensì un metodo : È intervenuto nuovamente l'interprete che ha trasformato la definizione che precedentemente "ha preparato" in qualcosa di nuovo, estremamente specifico ed a se stante, infatti, supponendo di definire due istanze alla stessa classe esse non saranno uguali ed avranno indirizzi di memoria diversi

x = MyClass()
y = MyClass()
x == y
False
repr(x)
'<__main__.MyClass object at 0x7f2c75a4b820>'
repr(y)
'<__main__.MyClass object at 0x7f2c75a4b8b0>'
In sostanza l'interprete ha trasformato l'originale MyClass.f da generica funzione a qualcosa d'altro (metodo) che è specifico per i singoli oggetti creati tramite la classe ... è questa specificità ("<<appartenenza>>" nel tutorial) che distingue un metodo da una funzione, oltre, naturalmente, al riferimento alla specifica istanza dell'oggetto stesso (il convenzionale "self", come certo sai).

Delizioso è notare il caso di mancata definizione del riferimento allo oggetto istanziato in MyClass.f

class MyClass:
    i = 12345
    def f():
        return 'hello world'

    
print(MyClass.f)
<function MyClass.f at 0x7f2c6f6df490>
print(MyClass.f())
hello world
x = MyClass()
print(x.f)
<bound method MyClass.f of <__main__.MyClass object at 0x7f2c75a4a020>>
print(x.f())
Traceback (most recent call last):
  File "/usr/lib/python3.10/idlelib/run.py", line 578, in runcode
    exec(code, self.locals)
  File "<pyshell#16>", line 1, in <module>
TypeError: MyClass.f() takes 0 positional arguments but 1 was given
A livello di classe f viene eseguita tranquillamente, dato che è una funzione, ma a richiamarla da un oggetto l'interprete si "arrabbia", essendo diventato un "metodo" non conforme al data-model previsto e non riferibile alla istanza definita.




Con 'sta tiritera ho cercato di esporre ciò che credo di aver capito io sull'argomento, probabilmente toppo su qualcosa, è un argomento per conoscenze più raffinate della mia, magari qualcuno più capace interverrà, in ogni caso non mi dispiacerebbe sapere cosa ne pensi Tu.




Ciao :)

Fatti non foste a viver come bruti...
comunque si vede che gia' conosci ambiente OOP e condivido che a differenza di altri linguaggi in Python non bisogna preoccuparsi quasi di nulla,

io invece conosco Python da un po, ma solo per i comandi base, da poco mi sto approcciando alla mentalita' di oggetti ed e' abbastanza tosta.

nella sintesi che hai fatto hai analizzato perfettamente le differenze tra metodo e funzione

quindi direi che anche se costruite su altro linguaggio, hai delle forti conoscenze basi

che di sicuro ti saranno molto utile per Python o nel caso anche per altri linguaggi.

un saluto e grazie per tutto :fingers-crossed:



Pagina: 1



Esegui il login per scrivere una risposta.