2012-01-20 22 views
5

In MATLAB, posso creare una matrice di struttura (struct) attenendo alla seguente procedura.Creare un oggetto senza chiamare una classe

person.name = 'Mike'; 
person.age = 25; 
person.gender = 'male'; 

in cui la persona non è definita prima di creare la struttura. Quando provo a farlo in python, mi dà un errore

name 'person' is not defined 

C'è un modo simile di farlo in Python? Grazie

EDIT: Essendo nuovo per Python, continuo a pensare in MATLAB. Il problema che ho è che ho una funzione che richiederà più input (più di 40), quindi invece di avere una funzione (input1, input2, ..., input40), avrò solo la funzione (input) dove l'input consistono in input.1, input.2, .., input.40.

+1

L'approccio di Matlab ha molto poco senso. Perché vorresti fare qualcosa del genere in Python? Cosa c'è di sbagliato nel fare cose in Python seguendo le regole del linguaggio Python? Perché provare ad imporre le regole di una lingua diversa su Python? –

+0

Ciao S.Lott, guarda il mio commento sulla risposta di kindall qui sotto. – mikeP

+0

Vuoi davvero un dizionario python –

risposta

6

Python non sarà magicamente creare un oggetto contenitore quando si inizia ad assegnare attributi ad esso, e se Matlab lo consente, considererei il MATLAB malamente rotto. Considerate questo:

person.name = "Mike" 
persom.age = 25 
person.sex = "Male" 

Ora abbiamo due oggetti, person e persom, e person non ha age, e non c'era alcun indizio che questo è accaduto. Più tardi provi a stampare person.age e, si spera, Matlab si lamenti poi ... due pagine dopo l'errore vero e proprio.

Una classe può essere utilizzata come contenitore o spazio dei nomi. Non c'è bisogno di istanziarlo, e ti farà risparmiare un po 'di battitura se vuoi solo un fascio di attributi.

class sex: 
    male = "M" 
    female = "F" 

class person: 
    name = "Mike" 
    age = 25 
    sex = sex.male 

Per accedere o modificare uno di questi, è possibile utilizzare person.name, ecc

N.B. Ho usato una classe per sex e per illustrare uno dei vantaggi di farlo: fornisce coerenza nei valori dei dati (senza ricordare se hai usato "M" o "Male" o "male") e cattura errori di battitura (cioè Python si lamenterà a proposito di sex.mlae ma non della stringa "mlae" e se in seguito la si verificava con "maschio", quest'ultimo fallirebbe).

Naturalmente, si corre ancora il rischio di errore ortografico name, age o sex in questo tipo di definizione di classe. Quindi quello che puoi fare è usare la classe come modello e creare un'istanza.

class Person: 
    def __init__(self, name, age=None, sex=None): 
     self.name, self.age, self.sex = name, age, sex 

Ora, quando lo fai:

person = Person("Mike", 25, sex.male) 

o se si desidera documentare ciò che tutti questi parametri sono:

person = Person("Mike", age=25, sex=sex.male) 

è praticamente impossibile da finire con un oggetto che ha un nome di attributo errato. Se lo incasini, Python ti darà un messaggio di errore nel punto in cui hai commesso l'errore. Questa è solo una ragione per farlo in questo modo.

+0

Il tuo ultimo suggerimento è il migliore. Con il penultimo, puoi rovinare l'ordine, ad es. 'person = Person (" Mike ", sex.male, 25)' –

+0

Grazie kindall. La tua spiegazione è chiara e molto utile. Sono d'accordo che si tratta di un errore comunemente riscontrato in MATLAB. Se posso descrivere un po 'perché ho fatto la domanda. Essendo nuovo in Python, continuo a pensare in MATLAB. Il problema che ho è che ho una funzione che richiederà più input (più di 40), quindi invece di avere una funzione (input1, input2, ..., input40), avrò solo la funzione (input) dove l'input consistono in input.1, input.2, .., input.40. La mia soluzione matlab-centric potrebbe non essere possibile in Python e potrei dover ripensare la soluzione. Grazie – mikeP

+0

Si potrebbe provare ad aggiungere ogni input a un elenco e ad accedere a ciascun valore di input dall'indice dell'elenco. L'ordine avrebbe importanza, però, e non è una soluzione flessibile come quella sopra. – Michael0x2a

3

probabilmente avrete bisogno di un dizionario (hash, array associativo):

person = {'name': 'Mike', 'age': 25} 
7

In Python, person deve essere un'istanza di una classe; non può materializzarsi solo dal nulla.

Si potrebbe ottenere qualcosa di simile al codice in questo modo:

class Struct(object): pass 

person = Struct() 
person.name = 'Mike' 
person.age = 25 
person.gender = 'male' 

print(person.__dict__) 

Questo stampa:

{'gender': 'male', 'age': 25, 'name': 'Mike'} 
11

In Python è possibile aggiungere i membri in modo dinamico a una classe esistente, ma che nome deve essere conosciuto essere del tipo di qualche classe. Per farlo è possibile creare una classe vuota:

class Empty: 
    pass  # empty statement otherwise the class declaration cannot succeed 

costruire la variabile come un esempio di esso

person = Empty() 

e quindi aggiungere qualsiasi dati che si desidera

person.name = 'Mike' 
person.age = 25 
person.gender = 'male' 

D'altra parte , se non hai bisogno delle funzionalità aggiuntive fornite da una classe "normale" e vuoi solo memorizzare alcuni dati in chiave => valore moda, puoi semplicemente usare un dizionario.

person={} 
person['name']='Mike' 
person['age']=25 
person['gender']='male' 

(notare che, almeno fino a Python 2.7, questo è per lo più solo una differenza stilistica, dal momento che le classi sono implementate sotto in termini di dizionari)

0

Mentre consiglierei NPE o Matteo come metodo preferito, poiché le funzioni sono oggetti di prima classe in python, possono anche essere usati per emulare una classe vuota, ma non possono essere istanziati come più oggetti (quindi avresti solo una istanza di oggetto per funzione).

>>> def person():pass 
... 
>>> person.name = 'Mike' 
>>> person.name 
'Mike' 
>>> person 
<function person at 0x020CF2F0> 

E 'strano, quindi non mi consiglia di utilizzare questo, ma non illustrare che le funzioni sono oggetti di prima classe in Python.

Problemi correlati