список пропусков Python из класса с использованием глобального оператора - PullRequest
0 голосов
/ 13 мая 2018

Я хочу заполнить список в классе, но я не нахожу способ передать его из вызывающего модуля в класс и / или обратно.Вот вызывающий модуль:

from NamesClass import Names
global TABLE, Names_db
TABLE = []
Names_db = []
RDATAPATH = "C:/users/richo/documents/python/Name Data/yob.txt"
L = Names.LoadTable(RDATAPATH)
print(L, len(Names_db))

Печать возвращает 1888 0. Два числа должны быть одинаковыми. Вот код класса:

class Names:
    def __init__(self):
        pass
    def LoadTable(rdatapath):
        """ load and sort a list from the text file
            return the length of the list """
        global TABLE, Names_db
        TABLE = []
        Names_db = []
        first_time = True
        with open(rdatapath) as f:
         for line_of_text in f:
             line_of_text = line_of_text.strip()
             aname = line_of_text.split(',')
             TABLE.append(aname[1]+','+aname[0]+','+aname[2]+','+aname[3]) #name, year, sex, occurences
        TABLE.sort() #sort by name
        for i, a_record in enumerate(TABLE):
            record = a_record.split(',')
            if first_time:
                previous_name = record[0]
                previous_sex = record[2]
                sum = 0
                first_time = False
            if previous_name != record[0]:
                Names_db.append(str(i)+previous_name+previous_sex+str(sum))
                sum = 0
                first_time = True
            previous_name = record[0]
            previous_sex = record[2]
            sum += int(record[3])
        return(len(Names_db))

Ответы [ 3 ]

0 голосов
/ 13 мая 2018

Прежде всего - вы можете сделать код более надежным, передав таблицу в качестве аргумента Names.LoadTable.Эта функция может добавлять имена в таблицу, не создавая ее заново.Вот урезанная версия

TABLE = []

class ModifiesTables:

    @classmethod
    fill_table(cls, incoming_table):
        # real logic would go here
        for n in range(100):
            incoming_table.append(n)


 ModifiesTables.fill_table(TABLE)
 print(TABLE)
 #  [0,1,2.....]

, вам, несомненно, скажут, что глобальные перемены - это плохая идея, и они есть.Однако если вы создадите таблицу вне функции - например, как я это делал выше - она ​​будет доступна для функций , определенных в той же области действия , без дополнительной работы.Вышеприведенный пример также может выглядеть следующим образом:

  TABLE = []

  def fill_table():
      for n in range(100):
          TABLE.append(n)

Однако это работает только в той же области действия , и ваш пример выглядит так, как будто вы объявляете «глобальную» таблицу в однойфайл и класс в другом.В этом случае лучше использовать первый пример, потому что отношения понятны, а не неявны (и вам не нужно беспокоиться, если, например, вы решили переместить вещи в разные файлы).

Хотя Pythonимеет глобальное ключевое слово, оно вам понадобится только в том случае, если вы присваиваете глобальному, а не просто используете его.Так что это работает:

   TABLE = []

   def works():
       TABLE.append("I work")  #using, not assigning

но это не

   def does_not_work():
       TABLE = []  # this declares a local with the same name, the original is ignored

, в этом случае вам понадобится глобальное:

   def works_but_use_sparingly():
       global TABLE
       TABLE = [] # this will replace TABLE with a new list

Официальное объяснение этого поведенияis:

В Python переменные, на которые ссылаются только внутри функции, неявно глобальны.Если переменной присваивается значение где-либо в теле функции, она считается локальной, если только она явно не объявлена ​​как глобальная.

Хотя сначала это немного удивляет, это объясняется моментальным рассмотрением.С одной стороны, требование наличия глобальных для назначенных переменных обеспечивает защиту от непреднамеренных побочных эффектов.С другой стороны, если бы глобальный требовался для всех глобальных ссылок, вы бы использовали глобальный все время.Вы должны будете объявить как глобальную каждую ссылку на встроенную функцию или компонент импортируемого модуля.Этот беспорядок отрицает полезность глобальной декларации для определения побочных эффектов.

Многое в этом вопросе .

0 голосов
/ 14 мая 2018

Спасибо. Я учу себя и занимаюсь этим как хобби. У меня есть рабочая версия, написанная inline, и классы не нужны, но я хотел научиться их использовать. Ваши ответы дают мне то, что мне нужно, чтобы продолжить. Спасибо, что нашли время. Хотел бы я иметь твои знания.

Далее я собираюсь узнать, как использовать Django для размещения моей программы в Интернете, и я уже запутался, но пока никого не буду беспокоить своими вопросами.

0 голосов
/ 13 мая 2018

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

TABLE = []
Names_db = []
Names.LoadTable(RDATAPATH, TABLE, Names_db)
print(len(Names_db))

А в классе:

def LoadTable(rdatapath, table, names_db):

Тогда просто используйте table и names_db при добавлении и сортировке. Вам не нужно ничего возвращать.

...