2016-02-25 15 views
8

ottengo l'errore:Tipo Hinting per gli oggetti di tipo che è in via di definizione

NameError: name 'OrgUnit' is not defined 
class OrgUnit(object): 

    def __init__(self, 
       an_org_name: str, 
       its_parent_org_unit: OrgUnit= None 
       ): 
     self.org_unit_name = an_org_name 
     self.parent_org_unit = its_parent_org_unit 

    def __str__(self): 
     if self.parent_org_unit: 
      parent_org_unit_name = self.parent_org_unit.__str__() 
      return parent_org_unit_name + "->" + self.org_unit_name 
     else: 
      return self.org_unit_name 


if __name__ == '__main__': 
    ibm_worldwide = OrgUnit("IBM_Worldwide") 
    ibm_usa = OrgUnit("IBM_USA", ibm_worldwide) 
    ibm_asia = OrgUnit("IBM_Asia", ibm_worldwide) 
    ibm_china = OrgUnit("IBM_China", ibm_asia) 
    print(ibm_worldwide) 
    print(ibm_usa) 
    print(ibm_asia) 
    print(ibm_china) 

Sono sicuro che questo è un paradigma noto, come sembra come un problema piuttosto comune l'uso di classe gerarchica (una classe autoreferenziale). So che potrei cambiare il tipo di its_parent_org_unit per essere object e funziona, ma questa sembra la cosa sbagliata da fare, soprattutto dal momento che confuta la mia capacità di controllare i tipi nelle mie chiamate. Con its_parent_org_unit cambiato ad essere un tipo object ottengo i risultati corretti:

IBM_Worldwide 
IBM_Worldwide->IBM_USA 
IBM_Worldwide->IBM_Asia 
IBM_Worldwide->IBM_Asia->IBM_China 

Sono aperto a pensieri e suggerimenti. Qual è il modo più "pythonic" per fare questo genere di cose?

PS: Qual è il nome di questo tipo di paradigma/problema di "classe autoreferenziale", che potrei utilizzare per cercare altri suggerimenti?

+1

Si prega di leggere [questo] (http://stackoverflow.com/questions/2489669/function-parameter-types-in-python) e tuffarsi "duck typing ";) – flaschbier

+2

Tsk, @flaschbier, se vuole usare suggerimenti tipo, lasciatelo fare. –

risposta

14

Il problema è che si desidera utilizzare i suggerimenti sui tipi ma si desidera che questa classe sia in grado di assumere argomenti del proprio tipo.

I suggerimenti tipo PEP (0484) spiegano che è possibile utilizzare string version of the type's name as a forward reference. Nell'esempio c'è una struttura dati Tree che suona molto simile a questa OrgUnit.

Per esempio, questo funziona:

class OrgUnit(object): 

    def __init__(self, 
       an_org_name: str, 
       its_parent_org_unit: 'OrgUnit' = None 
       ): 
+0

Funziona, tuttavia non genera alcun problema con un tipo non valido come una stringa, ad esempio: failure_case = OrgUnit ("Bad Unit", "a String")! Non c'è errore in questo caso. –

+0

"Non vi sono errori in questo caso"? Durante l'esecuzione? Perché ti aspetteresti un errore? –

+0

re. "non c'è errore". Python è ** non ** Java _on purpose_ :-) – miraculixx