Deseo crear un archivo que contenga una lista de diccionarios de búsqueda estática. Todos los demás archivos del proyecto accederían a este archivo, así que esencialmente estoy tratando de evitar la redundancia de datos y poner un control centralizado.

Para hacerlo, creé una clase, creé diccionarios de búsqueda y agregué métodos getter para acceder. Pero cuando trato de usar el dict, parece que mis métodos get no pueden ser compatibles con los dictados declarados globalmente.

Así es como se ve mi código:

class global_lookup: 

    PROVINCE_DICT = {
        "AB" : "Alberta",
        "BC" : "British Columbia",
        "MB" : "Manitoba",
        "NB" : "New Brunswick",
        "NL" : "Newfoundland and Labrador",
        "NT" : "Northwest Territories",
        "NS" : "Nova Scotia",
        "NU" : "Nunavut",
        "ON" : "Ontario",
        "PE" : "Prince Edward Island",
        "QC" : "Quebec",
        "SK" : "Saskatchewan",
        "YT" : "Yukon"
    }

    def get_province_short(province_long):
        for prov_shrt, prov_long in PROVINCE_DICT.items():
            if province_long == prov_long:
                return prov_shrt
            else:
                raise DatahubError(F"get_province_short - Province data for {province_long} could not be located")    

    def get_province_long(province_short): 
        if province_short in PROVINCE_DICT.keys():
            return PROVINCE_DICT[province_short]
        else:
            raise DatahubError(F"get_province_long - Province data for {province_short} could not be located")

Como esto va a ser una sentencia estática, tengo la intención de incluir esta clase y llamar a los métodos para acceder a los nombres de provincia largos y cortos.

Por ejemplo, estoy llamando esto desde otra clase usando:

global_lookup.get_province_long('ON')

Y el error que obtengo es:

`name 'PROVINCE_DICT' is not defined

Espero que 'Ontario' sea devuelto.

¿Qué estoy haciendo mal?

-1
Sushant Vasishta 11 oct. 2019 a las 21:39

3 respuestas

La mejor respuesta

Este diccionario será un atributo de cada instancia de la clase. Por convención, la instancia se llama self dentro de un método. Se pasa a cada método automáticamente, como primer argumento. Eso le permite referirse a la instancia: se llama self. Entonces puedes obtener las cosas que posee.

Prueba esto:

class GlobalLookup:  # More conventional class name in Python

    PROVINCE_DICT = {
        "AB" : "Alberta",
        "BC" : "British Columbia",
        "MB" : "Manitoba",
        "NB" : "New Brunswick",
        "NL" : "Newfoundland and Labrador",
        "NT" : "Northwest Territories",
        "NS" : "Nova Scotia",
        "NU" : "Nunavut",
        "ON" : "Ontario",
        "PE" : "Prince Edward Island",
        "QC" : "Quebec",
        "SK" : "Saskatchewan",
        "YT" : "Yukon"
    }

    def get_province_short(self, province_long):
        for prov_shrt, prov_long in self.PROVINCE_DICT.items():
            if province_long == prov_long:
                return prov_shrt
        else:
            raise DatahubError(f"get_province_short - Province data for {province_long} could not be located")    

    def get_province_long(self, province_short): 
        prov_long = self.PROVINCE_DICT.get(province_short)
        if prov_long is None:
            raise DatahubError(f"get_province_long - Province data for {province_short} could not be located")
        return prov_long

También utilicé el método get en el diccionario, porque está ahí.

Tenga en cuenta que else en get_province_short() debe estar en for, porque solo desea generar un error si el bucle for finaliza normalmente.

1
kwinkunks 11 oct. 2019 a las 20:04

PROVINCE_DICT es un atributo de clase de global_lookup. No se agrega automáticamente al espacio de nombres de los métodos. Como tiene la intención de llamar a estos métodos directamente desde la clase y necesita acceso a los atributos de la clase, debe declarar estos métodos como métodos de clase. Por ejemplo:

@classmethod
def get_province_short(cls, province_long):
    for prov_shrt, prov_long in cls.PROVINCE_DICT.items():
        if province_long == prov_long:
            return prov_shrt
        else:
            raise DatahubError(F"get_province_short - Province data for {province_long} could not be located") 

Tenga en cuenta el decorador @classmethod que hará que se agregue una referencia a la clase a la firma del método. Utilizamos esa referencia (cls) para acceder a PROVINCE_DICT.

1
glibdud 11 oct. 2019 a las 19:01

PROVINCE_DICT es una variable de instancia, por lo que podemos acceder directamente a la variable de instancia a través del nombre de la clase, como class_name.variable_name en el método de la clase.

class global_lookup: 

    PROVINCE_DICT = {
      "AB" : "Alberta",
      "BC" : "British Columbia",
      "MB" : "Manitoba",
      "NB" : "New Brunswick",
      "NL" : "Newfoundland and Labrador",
      "NT" : "Northwest Territories",
      "NS" : "Nova Scotia",
      "NU" : "Nunavut",
      "ON" : "Ontario",
      "PE" : "Prince Edward Island",
      "QC" : "Quebec",
      "SK" : "Saskatchewan",
      "YT" : "Yukon"
    }

    def get_province_short(province_long):
        for prov_shrt, prov_long in global_lookup.PROVINCE_DICT.items(): #updated
            if province_long == prov_long:
                return prov_shrt
            else:
                raise DatahubError(F"get_province_short - Province data for {province_long} could not be located")    

    def get_province_long(province_short): 
        if province_short in global_lookup.PROVINCE_DICT.keys(): # update
            return global_lookup.PROVINCE_DICT[province_short] #updated
        else:
            raise DatahubError(F"get_province_long - Province data for {province_short} could not be located")

Llamada al método: print(global_lookup.get_province_long('ON'))

Salida: ingrese la descripción de la imagen aquí

1
Dharmesh 11 oct. 2019 a las 19:17
58346825