Tengo un diccionario de un módulo importado asignado a una variable de clase. Intento imprimir la variable directamente desde la instancia, me da todo el diccionario (bien). Pero cuando trato de obtener un valor de una clave en dicho diccionario, recibo un error de nombre.

Aquí está mi código principal:

import list_module

class Calculator(object):
    tile_chart = list_module.tile_sizes

    def __init__(self, dims_string):
        self.dims_string = dims_string
        self.grout_choice_input = input('Input grout thickness.\n>')
        self.grout_choice = self.grout_choice_input.strip('\"')

    def main(self):
        if self.dims_string in tile_chart:
            self.my_tile_size = tile_chart.get('dims_string')
            self.grout_line_index = self.grout_lines.index(self.grout_choice)
            return self.my_tile_size[self.grout_line_index]
        else:
            print("not configured yet")

calculator_instance = Calculator(table_str)
print(Calculator.tile_chart)
print(calculator_instance.tile_chart)
calculator_instance.main()

Aquí está el código que estoy importando, llamado list_module.py:

tile_sizes = { 
         '1x1' : [90,45,29,22,14,10,7,5],
         '2x2' : [186,93,61,45,29,22,17,10],
         '3x3' : [284,142,93,69,45,33,26,15],
         '4.25x4.25' : [404,202,134,99,65,48,38,25],
         '4x8' : [254,127,84,63,42,31,25,15],
         '6x6x1/4' : [570,285,190,142,93,69,55,35],
         '6x6x1/2' : [286,143,95,71,47,35,28,15],
         '8x8' : [510,255,169,126,84,62,50,30],
         '12x12' : [766,383,253,191,126,94,75,45],
         '13x13' : [830,415,275,207,137,102,82,50],
         '16x16' : [1020,510,340,255,169,126,101,60],
         '18x18' : [1150,575,383,288,191,142,114,70],
         '20x20' : [1280,640,452,320,212,159,126,75],
         '24x24' : [1536,768,510,383,255,191,152,95]
         }

grout_lines = ["1/16","1/8","3/16","1/4","3/8","1/8","5/8","1"]

Aquí está la impresión:

{'1x1': [90, 45, 29, 22, 14, 10, 7, 5], '2x2': [186, 93, 61, 45, 29, 22, 17, 10], '3x3': [284, 142, 93, 69, 45, 33, 26, 15], '4.25x4.25': [404, 202, 134, 99, 65, 48, 38, 25], '4x8': [254, 127, 84, 63, 42, 31, 25, 15], '6x6x1/4': [570, 285, 190, 142, 93, 69, 55, 35], '6x6x1/2': [286, 143, 95, 71, 47, 35, 28, 15], '8x8': [510, 255, 169, 126, 84, 62, 50, 30], '12x12': [766, 383, 253, 191, 126, 94, 75, 45], '13x13': [830, 415, 275, 207, 137, 102, 82, 50], '16x16': [1020, 510, 340, 255, 169, 126, 101, 60], '18x18': [1150, 575, 383, 288, 191, 142, 114, 70], '20x20': [1280, 640, 452, 320, 212, 159, 126, 75], '24x24': [1536, 768, 510, 383, 255, 191, 152, 95]}
{'1x1': [90, 45, 29, 22, 14, 10, 7, 5], '2x2': [186, 93, 61, 45, 29, 22, 17, 10], '3x3': [284, 142, 93, 69, 45, 33, 26, 15], '4.25x4.25': [404, 202, 134, 99, 65, 48, 38, 25], '4x8': [254, 127, 84, 63, 42, 31, 25, 15], '6x6x1/4': [570, 285, 190, 142, 93, 69, 55, 35], '6x6x1/2': [286, 143, 95, 71, 47, 35, 28, 15], '8x8': [510, 255, 169, 126, 84, 62, 50, 30], '12x12': [766, 383, 253, 191, 126, 94, 75, 45], '13x13': [830, 415, 275, 207, 137, 102, 82, 50], '16x16': [1020, 510, 340, 255, 169, 126, 101, 60], '18x18': [1150, 575, 383, 288, 191, 142, 114, 70], '20x20': [1280, 640, 452, 320, 212, 159, 126, 75], '24x24': [1536, 768, 510, 383, 255, 191, 152, 95]}
Traceback (most recent call last):
  File "ultracolor_calc_oop.py", line 68, in <module>
    calculator_instance.main()
  File "ultracolor_calc_oop.py", line 53, in main
    if self.dims_string in tile_chart:
NameError: name 'tile_chart' is not defined

Como puede ver, el diccionario tile_chart se imprime perfectamente cuando se lo llama a nivel de clase e instancia. Tal vez tengo un malentendido fundamental sobre lo que constituye 'definición', pero para mí, la capacidad de impresión implica que está definido. Sin embargo, tan pronto como ejecuto main(), aparece un error de nombre que dice que no está definido.

¿Alguna orientación?

0
bear-knuckle 27 feb. 2018 a las 01:51

3 respuestas

La mejor respuesta

Cambie las referencias de su método dentro de main() de tile_chart a self.tile_chart.

Ha definido la variable a nivel de clase en lugar de a nivel de método. Por lo tanto, para llamar a la variable, debe consultar self.

0
jpp 26 feb. 2018 a las 22:54

Use self.tile_chart en lugar de tile_chart en su función principal. Todos los elementos del objeto serán referenciados usando self.

import list_module

class Calculator(object):
    tile_chart = list_module.tile_sizes

    def __init__(self, dims_string):
        self.dims_string = dims_string
        self.grout_choice_input = input('Input grout thickness.\n>')
        self.grout_choice = self.grout_choice_input.strip('\"')

    def main(self):
        if self.dims_string in self.tile_chart:
            self.my_tile_size = self.tile_chart.get('dims_string')
            self.grout_line_index = self.grout_lines.index(self.grout_choice)
            return self.my_tile_size[self.grout_line_index]
        else:
            print("not configured yet")

calculator_instance = Calculator(table_str)
print(Calculator.tile_chart)
print(calculator_instance.tile_chart)
calculator_instance.main()
0
jhandei 26 feb. 2018 a las 23:02

Ha definido la variable a nivel de clase en lugar de a nivel de método. Por lo tanto, para llamar a la variable tienes que referirte a self

Sí, eso funciona en lecturas, porque accedes a través de la instancia, que no tiene un atributo con ese nombre, por lo que la búsqueda sube a la clase, que tiene el atributo. Y funciona también con escrituras en el lugar (escribiendo en el interior de algunas var compuestas como dict o list). Pero no cuando se asigna un nuevo objeto al nombre.

Es decir, tenga en cuenta que puede cambiar la variable de clase en el lugar, usando el calificador self, pero si asigna otro objeto a la variable de clase, usando el calificador self, eso creará un nuevo variable de instancia con ese nombre, desconectada de la variable de clase. Si esa es una variable de clase verdadera, compartida por todas las instancias, use Calculator.tile_chart, no self.tile_chart, para estar seguro de lecturas y escrituras.

0
progmatico 26 feb. 2018 a las 23:31