Путаница в отношении объема и видимости переменной и аргумента в функции - PullRequest
0 голосов
/ 19 февраля 2020

Я не понимаю, почему test1 и test2 будут возвращать 2 разных вывода, когда они одинаковы.

   python3.7.4

   fin=open('D:\Python\Think Python\words.txt')

   def build_list_append(file):
       word_list=[]
       for line in fin:
           word=line.strip()
           word_list.append(word)
       return word_list

   def test1(worklist1=build_list_append(fin)):
       print("This is test1,It will return a non-empty list")
       print(len(worklist1))

   def test2(worklist2=build_list_append(fin)):
       print("This is test2,It will return an empty list")
       print(len(worklist2))

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Попробуйте запустить программу снова, за исключением оператора fin = open(...) внутри функции build_list_append() (обязательно добавьте также fin.close() в конце). Затем они будут действовать так же.

Файловые объекты в python (возвращаемые open()) принадлежат классу объектов, называемому generator *. Генераторы являются итеративными и лениво возвращают элемент за элементом по мере необходимости. Что отличает их, скажем, от списков, так это то, что вы не можете go назад в генераторе - вы можете получить только следующий элемент. Поэтому, когда у вас заканчиваются элементы, вы ничего не получаете.

Вот что здесь происходит. L oop for line in fin исчерпывает все элементы, которые может создать файловый объект, при первом запуске. Когда вы выполняете его снова, генератору больше нечего отдавать, и поэтому for l oop не запускается, и вы получаете пустой список. Если вы заново не создадите генератор с самого начала, снова вызвав open(), в нем закончатся элементы.


* это сложнее, чем это, и технически файловые объекты не являются генераторами, но они действуют достаточно похоже, чтобы провести сравнение.

0 голосов
/ 19 февраля 2020

Краткий ответ : Это потому, что после вызова test1() указатель чтения переместится в конец файла. После вызова test2() не осталось строк для чтения, следовательно, длина 0.

Длинный ответ:

При fin = open('D:\Python\Think Python\words.txt') чтение указатель будет указывать на начало файла.

После вызова file1() он будет вызывать build_list_append(fin), который будет последовательно перебирать файл. Из-за этого все строки будут сохранены в word_list и будет возвращена длина.

Теперь указатель указывает на конец файла.

После вызова test2(), программа снова вызывает build_list_append(fin), который хочет, чтобы перебирал весь файл построчно, , но так как указатель уже находится в конце файла, он не имеет никакого контента от go до . Следовательно, возвращается длина 0.

Если вы попытаетесь закрыть файл и передать файловый объект fre sh, test2() вернет то же значение, что и test1().

...