Модуль Python недоступен для работы внутри класса

#python-3.x #jupyter-notebook

#python-3.x #jupyter-notebook

Вопрос:

Приведенный ниже код работает так, как ожидалось. Он печатает 5 случайных чисел.

 import numpy as np

class test_class():
    def __init__(self):
        self.rand_nums = self.create_rand_num()

    def create_rand_num(self):
        numbers = np.random.rand(5)
        return numbers

myclass = test_class()
myclass.rand_nums
  

Однако следующее не работает. Ошибка имени: имя ‘np’ не определено

 import numpy as np
from test.calc import create_rand_num

class test_class():
    def __init__(self):
        self.rand_nums = create_rand_num()

myclass = test_class()
myclass.rand_nums

# contents of calc.py in test folder:
def create_rand_num():
    print(np.random.rand(5))
  

Но это работает:

 from test.calc import create_rand_num

class test_class():
    def __init__(self):
        self.rand_nums = create_rand_num()

myclass = test_class()
myclass.rand_nums

# contents of calc.py in test folder:
import numpy as np
def create_rand_num():
    print(np.random.rand(5))
  

Почему я должен иметь ‘import numpy as np’ внутри calc.py ? У меня уже есть этот импорт до определения моего класса. Я уверен, что здесь я что-то недопонимаю, но я пытался следовать общему правилу размещать все инструкции import в верхней части основного кода.

Что меня смущает, так это то, что когда я говорю «из test.calc импортировать create_rand_num», как Python узнает, включен ли «import numpy as np» в начало calc.py или нет? Он должен каким-то образом знать, потому что, когда я включаю его, код работает, но когда я его не включаю, код не работает.

РЕДАКТИРОВАТЬ: После прочтения ответа от @DeepSpace я хочу задать следующий вопрос:

Предположим, у меня есть следующий файл.модуль py с содержимым, перечисленным как показано:

 import numpy as np
import pandas as pd
import x as y

def myfunc():
   pass
  

Итак, если у меня есть другой файл, file1.py и в нем я говорю из file.py импортируйте myfunc, получу ли я доступ к np, pd и y? Это именно то, что, похоже, происходит в моем третьем примере выше.

В моем третьем примере обратите внимание, что np НИГДЕ не определен в основном файле, он определен только в calc.py файл, и я не импортирую * из calc.py я импортирую только create_rand_num. Почему я не получаю ту же ошибку NameError?

Ответ №1:

Python не похож на C. При импорте модуля не копируется-вставляется его исходный код. Он просто добавляет ссылку на него в locals() «пространство имен». import numpy as np наличие в одном файле не делает его волшебным образом доступным во всех других файлах.

Вы должны import numpy as np в каждом файле, который хотите использовать np .

Возможно, стоит прочитать:https://docs.python.org/3.7/reference/simple_stmts.html#the-import-statement

Комментарии:

1. Спасибо. Я думал, что ‘из модуля import func’ будет импортироваться только func, ничего больше. Почему это имело бы значение, если бы я включил ‘import numpy as np’ в начало func def? Я все равно должен получить NameError…

2.@Murchak Потому что, если вы не import numpy as np в том же файле, np не определено

3. Я думаю, что мне многое ясно. Я хочу уточнить: если я импортирую определенную функцию из файла. модуль py, получаю ли я доступ ко всем импортированным модулям, перечисленным в файле. модуль py, или импорт импортирует только функцию и ничего больше? Извините, я не знаю, как еще больше прояснить свой вопрос.

4. Спасибо @DeepSpace. Просто чтобы завершить это: если у меня есть класс, содержащийся в myclass.py файл, который использует целую кучу пользовательских функций, содержащихся в разных файлах .py, я должен импортировать необходимые модули в каждый из этих файлов, вместо того, чтобы извлекать их и помещать в myclass.py файл (содержащий код для моего класса)? Это правильно?