У меня есть словарь из импортированного модуля, назначенного переменной класса. Я пытаюсь напечатать переменную прямо из экземпляра, она дает мне весь словарь (хорошо). Но когда я пытаюсь получить значение из ключа в указанном словаре, я получаю ошибку имени.

Вот мой основной код:

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()

Вот код, который я импортирую, называется 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"]

Вот распечатка:

{'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

Как видите, словарь tile_chart прекрасно печатается при вызове на уровне класса и экземпляра. Может быть, у меня есть фундаментальное недопонимание того, что составляет «определение», но для меня печатность подразумевает, что оно определено. Тем не менее, как только я запускаю main(), я получаю сообщение об ошибке, в котором говорится, что оно не определено.

Любое руководство?

0
bear-knuckle 27 Фев 2018 в 01:51

3 ответа

Лучший ответ

Измените ссылки на методы внутри main() с tile_chart на self.tile_chart.

Вы определили переменную в классе, а не на уровне метода. Поэтому для вызова переменной необходимо обратиться к self.

0
jpp 26 Фев 2018 в 22:54

Используйте self.tile_chart вместо tile_chart в вашей основной функции. Все элементы объекта будут ссылаться с помощью 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 Фев 2018 в 23:02

Вы определили переменную в классе, а не на уровне метода. Поэтому, чтобы вызвать переменную, вы должны обратиться к себе

Да, это работает на чтение, потому что вы получаете доступ через экземпляр, который не имеет атрибута с таким именем, поэтому поиск идет до класса, который имеет этот атрибут. И работает также с записями на месте (запись внутрь некоторых составных переменных, таких как dict или list). Но не при назначении нового объекта имени.

То есть следует помнить, что вы можете изменить переменную класса на месте, используя квалификатор self, но если вы назначите другой объект переменной класса, используя квалификатор self, это создаст новый переменная экземпляра с таким именем, отключенная от переменной класса. Если это истинная переменная класса, общая для всех экземпляров, используйте Calculator.tile_chart, а не self.tile_chart, чтобы быть в безопасности при чтении и записи.

0
progmatico 26 Фев 2018 в 23:31