Domanda

Ho una serie di classi Python in un file. Alcune classi di riferimento gli altri.

Il mio codice è qualcosa di simile:

class A():
    pass

class B():
    c = C()

class C():
    pass

Il tentativo di eseguire tale, ho NameError: name 'C' is not defined. Va bene, ma c'è un modo per farlo funzionare, o devo manualmente riordinare le mie lezioni di accogliere? In C ++, posso creare un prototipo di classe. Ha Python ha un equivalente?

(In realtà sto giocando con modelli di Django, ma ho cercato di non complicare le cose).

È stato utile?

Soluzione

In Python non si crea un prototipo per sé, ma si ha bisogno di capire la differenza tra "gli attributi di classe" e gli attributi a livello di istanza. Nell'esempio che hai mostrato in precedenza, si dichiara un attributo di classe in classe B, non un attributo a livello di istanza.

Questo è quello che stai cercando:

class B():
    def __init__(self):
        self.c = C()

Altri suggerimenti

In realtà, tutto quanto sopra sono grandi osservazioni su Python, ma nessuno di loro sarà risolvere il problema.

Django ha bisogno di introspezione roba.

destro modo per fare ciò che si vuole è la seguente:

class Car(models.Model):
    manufacturer = models.ForeignKey('Manufacturer')
    # ...

class Manufacturer(models.Model):
    # ...

Si noti l'uso del nome della classe come stringa , piuttosto che il riferimento di classe letterale. Django offre questa alternativa per affrontare esattamente il problema che Python non fornisce dichiarazioni previsionali.

Questa domanda mi ricorda la classica domanda di supporto che si dovrebbe sempre chiedere a qualsiasi cliente con un problema: "Che cosa stai davvero cercando di fare"

Questo risolverebbe il problema come presentato (ma penso che cercate per un attributo esempio come jholloway7 risposto):

class A:
    pass

class B:
    pass

class C:
    pass

B.c = C()

Python non ha prototipi o classi aperte in stile Ruby. Ma se si ha realmente bisogno di loro, è possibile scrivere un metaclasse che sovraccarica nuovo in modo che non una ricerca nello spazio dei nomi corrente per vedere se la classe esiste già, e se lo fa ritorna il tipo di oggetto esistente piuttosto di crearne uno nuovo. Ho fatto qualcosa di simile su un ORM scrivo un po 'indietro e ha funzionato molto bene.

Tutte le risposte corrette circa classe vs attributi esempio. Tuttavia, la ragione si dispone di un errore è solo l'ordine di definire le vostre classi. Naturalmente Classe C non è stato ancora definito (come codice a livello di classe viene eseguito immediatamente durante l'importazione):

class A():
    pass

class C():
    pass

class B():
    c = C()

funzionerà.

Un decennio dopo viene posta la domanda, ho incontrato lo stesso problema. Mentre la gente suggeriscono che il riferimento dovrebbe essere fatto all'interno del metodo init, ci sono momenti in cui è necessario accedere ai dati come un "attributo di classe" prima della classe è in realtà un'istanza. Per questo motivo, sono venuto su con una soluzione semplice utilizzando un descrittore.

class A():
    pass

class B():
    class D(object):
        def __init__(self):
            self.c = None
        def __get__(self, instance, owner):
            if not self.c:
                self.c = C()
            return self.c
    c = D()

class C():
    pass

>>> B.c
>>> <__main__.C object at 0x10cc385f8>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top