2015-03-31 8 views
6

Durante la lettura fmark 's risposta alla domanda What are "named tuples" in Python? ho visto che l'esempio dato non aveva lo stesso nome e di riferimento, vale a dire la parola Point appare due volte nella seguente dichiarazione:
Il nome e il riferimento di una tupla con nome possono essere diversi?

Point = namedtuple('Point', 'x y')

Così sono andato al riferimento originale:
https://docs.python.org/2/library/collections.html#collections.namedtuple
E anche qui ho trovato altri due esempi:

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade') 
Color = namedtuple('Color', 'red green blue') 

Idealmente le parole non vengono ripetute in Python. Per esempio l'intera linea (per esempio la Point) potrebbe essere sostituito dal seguente:

namedtuple('Point', 'x y') 

O

Point = namedtuple('x y') 

Naturalmente, si assume che la tupla chiamato deve avere lo stesso nome e riferimento. Quindi la mia domanda è: quando è consigliabile (se è assolutamente consentito) che una tupla nominata debba avere un nome e un riferimento diverso? Devo ancora trovare un esempio.

+1

'namedtuple ('Punto' ...)' crea una classe denominata 'Punto', tuttavia senza assegnarla a qualche identificatore è possibile utilizzarla solo una volta, ad es. 'point1 = namedtuple ('Point', 'x y') (1, 0)', e 'type (point1) è '. È conveniente utilizzare un identificatore che corrisponde al nome della classe, ma non è necessario, ad es. 'Vertex = namedtuple ('Point' ...)'. Una classe è solo un altro oggetto in python e dovresti usare un nome diverso ogni volta che assegneresti un identificatore diverso a un nome di classe, ad es. 'Punto di classe: ... Vertex = Point' – AChampion

+2

A mio parere, il modulo' namedtuple' è un pasticcio orribile e dovrebbe essere stato scritto utilizzando metaclassi in primo luogo. Non è ancora del tutto chiaro per me [perché non lo era] (http://stackoverflow.com/questions/28184531), ma se lo fosse stato, avresti la possibilità di utilizzare le definizioni di classe per te tuple di nome, designare una metaclasse, non avendo bisogno di ripetere il nome della classe. –

risposta

10

Puoi farlo, ti infastidirà.

In [1]: import collections 

In [2]: Point = collections.namedtuple('Rectangle', 'x y') 

In [3]: Point(1, 2) 
Out[3]: Rectangle(x=1, y=2) 

Questo è confuso, non farlo a meno che non si abbia una buona ragione.

Il motivo per cui questo accade è perché namedtuple() è solo una funzione, non ha alcuna conoscenza specifica su come viene utilizzata come dichiarazione. Nelle lingue con macro, namedtuple() sarebbe una macro che invece si espande in una dichiarazione. Quindi, piuttosto che virare su un sistema macro o percorrere lo stack di chiamate per il nome, devi specificare il nome due volte.

Quindi è una delle "verruche" di Python, o un compromesso di progettazione, a seconda di come ci si sente al riguardo.

+1

In particolare: la ragione per cui succede 'namedtuple' è stata scritta usando' exec' e la formattazione delle stringhe invece di usare metaclassi (che hanno il primo argomento 'name' associato al nome dell'istanza della metaclasse fornita). Perchè è questo? [Chi lo sa.] (Http://stackoverflow.com/questions/28184531/why-doesnt-the-namedtuple-module-use-a-metaclass-to-create-nt-class-objects) –

+0

Sebbene sia giusto, devi ancora ripetere il nome della classe quando usi una metaclasse come factory di classe (ad esempio 'type ('name', (object,), {})'). –

Problemi correlati