Я делаю игру на Python, и у меня есть объект для хранения всех пользовательских настроек, называемый gameSettings
.
При запуске функций в отдельном файле (functions.py
) мне приходится создавать новую локальную переменную gameSettings
в каждой отдельной функции в файле.
# functions.py
def myFunc1(x, y, gameSettings):
if gameSettings.printX == True:
print(x)
def myFunc2(z, gameSettings):
if gameSettings.printZ == True:
print(z)
def myFunc3(a, b, gameSettings):
if gameSettings.add == True:
print(a+b)
elif gameSettings.subtract == True:
print(a-b)
# (example code)
Это также означает, что я должен запустить объект gameSettings
почти через каждую функцию, которую я написал до сих пор.
Мне было интересно, есть ли лучший способ сделать это, так как я сомневаюсь, что это очень эффективно. Я не могу просто импортировать объект gameSettings
при запуске (так как это приведет к циклическому импорту), но даже если бы я мог, переменные объекта могут быть изменены пользователем, и я предполагаю, что изменение объекта gameSettings
в main.py
не изменит его functions.py
коллега.
Зачем нужен круговой импорт? Укажите минимальный воспроизводимый пример.
gameSettings
в main.py
не изменит его аналог functions.py
» -- Почему вы так думаете? Если gameSettings
относится к одному и тому же объекту для обоих модулей (что звучит так), то оба модуля увидят любые изменения в нем.
gameSettings
создается и обновляется в main.py
, поэтому всякий раз, когда я пытаюсь импортировать его из main в functions, я получаю циклическую ошибку импорта.
Как вы видите это решение? Использование общего словаря. Исходя из своего опыта, я бы сохранил эти настройки в виде файла .json и загружал его при запуске игры.
main.py
from func1 import Func1
from func2 import Func2
class GameSettings():
def __init__(self, printX=False, printZ=False):
self.settings = { 'printX': printX, 'printZ': printZ }
settings = GameSettings(printX=True, printZ=False)
func1 = Func1(settings)
func1.myFunc1(1, 2)
print(func1.settings.settings)
settings.settings.update({'printX': False})
print(func1.settings.settings)
func1.myFunc1(1, 2)
func2 = Func2(settings)
func2.myFunc2(3)
settings.settings.update({'printZ': True})
func2.myFunc2(3)
func1.py
class Func1():
def __init__(self, settings=None):
self.settings = settings
def myFunc1(self, x, y):
if self.settings.settings['printX'] == True:
print(x)
func2.py
class Func2():
def __init__(self, settings=None):
self.settings = settings
def myFunc2(self, z):
if self.settings.settings['printZ'] == True:
print(z)
Вот результат выполнения этого кода
bash-5.1$ python3 main.py
1
{'printX': True, 'printZ': False}
{'printX': False, 'printZ': False}
3
То есть каждую функцию можно преобразовать в класс, и при запуске она будет наследовать значения для gameSettings
? Я думаю, что это все же может создать новые локальные экземпляры. И ручное обновление отдельных экземпляров может быть более болезненным.
Вы подсчитали, сколько раз myFunc2 вызывается на главной? Это два. Вы видели, сколько у вас отпечатков на выходе? Это 1. Изменение словаря настроек на main меняет словарь, который использует каждый класс.
@neutral Я добавил несколько дополнительных отпечатков, чтобы показать вам с другой точки зрения, что это действительно изменяет локальную переменную внутри каждого класса, когда вы меняете ее на своем основном
о, я думал, вы обновляете локальные экземпляры вместо глобального
В этом простом примере класс для хранения настроек может показаться сложным, но вы можете рассмотреть дополнительные методы и другие структуры внутри GameSettings.
Я думаю, что это могло бы ответить на мой вопрос, хотя мне пришлось бы изменить свой код с использования атрибутов gameSettings
на хранение словаря атрибутов внутри gameSettings
(что я, вероятно, должен был сделать раньше)
Потратьте несколько дополнительных секунд на обдумывание проектных решений на ранних стадиях проекта, чтобы сэкономить время в будущем. Будущее вы будете благодарить прошлое вас. Если это решило вашу проблему, пожалуйста, отметьте как правильное :)
о, так вызов gameSettings
в классе (Func1) и установка его в локальную переменную (Func1.settings) обновляет его вместе с глобальным экземпляром gameSettings
? Я предполагал, что он просто создаст локальный экземпляр, независимый от глобального.
это может быть полезно realpython.com/python-pass-by-reference
Вы можете просто создать экземпляр настроек игры в отдельном модуле, а затем импортировать его и изменить настройки в любом месте.
settings.py
class GameSettings:
pass
gameSettings = GameSettings()
main.py
from settings import gameSettings
gamesettings.score = 0
Важно понимать, что settings.py будет выполняться только один раз, независимо от того, сколько раз он будет импортирован, и каждый раз будет импортироваться один и тот же объект.
Если вы используете класс, вы можете инициировать gameSettings в конструкторе класса и получить доступ к объекту из каждого метода в этом классе.