Есть несколько неправильных вещей, поэтому давайте начнем с самого очевидного.
Если у вас есть класс MasterDef
, вызов MasterDef()
создает экземпляр этого класса.Если вы не назначите это переменной, этот экземпляр немедленно исчезнет.
Выполнение MasterDef.settings
в дальнейшем может сработать, если у класса есть атрибут класса или метод с именем settings
, но в этом случае вы не обращаетесь к атрибуту settings в экземпляре.
Типичнотакие глобальные параметры передаются или реализуются как функциональный объект, который выполняет загрузку только один раз, или превращаются в глобальную переменную (как показано в следующем примере).Упрощенно вы бы сделали:
from __future__ import print_function, absolute_import, division, unicode_literals
class MasterDef(object):
def __init__(self):
self.settings = dict(some='setting')
master_def = None
def function_1():
global master_def
if master_def is None:
master_def = MasterDef()
def function_2():
print('master_def:', master_def.settings)
if __name__ == '__main__':
function_1()
function_2()
, что дает:
master_def: {'some': 'setting'}
Несколько замечаний к вышесказанному:
- Если по какой-либо причине выделая что-то новое на Python 2.7, сделайте вещи более совместимыми с Python3, включив импорт
from
__future__
, как указано.Даже если вы просто используете функцию print
(вместо устаревшего оператора print
).Это упростит переход (2.7 в EOL в 2020 году) - Опять в 2.7 ваш базовый класс становится подклассом
object
, что позволяет, например, иметь свойства. - Путем проверки этого
master_def
is None
Вы можете вызывать function_1
несколько раз
Вы также должны знать, что PyYAML load
, как написано в его документации, может быть небезопасным, когда выне иметь полного контроля над вашим входом.Редко нужно использовать load()
, поэтому используйте safe_load()
или обновите мой пакет ruamel.yaml, который реализует более новый стандарт YAML 1.2 (выпущенный в 2009 году, поэтому нет оправдания использованию PyYAML, который до сих пор не поддерживает это).
Поскольку вы также, похоже, работаете в Windows (предполагается, что вы используете \\
), рассмотрите возможность использования необработанных строк, где вам не нужно экранировать обратную косую черту, используя os.path.join()
.Я опускаю вашу часть пути в моем полном примере, так как я не на Windows:
from __future__ import print_function, absolute_import, division, unicode_literals
import ruamel.yaml
class Import_Yaml_Setting(object):
def __init__(self, path):
self._path = path # stored in case you want to write out the configuration
self.settings = self.read_yaml(path)
def read_yaml(self, path):
yaml = ruamel.yaml.YAML(typ='safe')
with open(path, 'r') as stream:
return yaml.load(stream)
class MasterDef(Import_Yaml_Setting):
def __init__(self, path):
Import_Yaml_Setting.__init__(self, path)
master_def = None
def function_1():
global master_def
path = 'yaml_file.yaml'
if master_def is None:
master_def = MasterDef(path)
def function_2():
print('master_def:', master_def.settings)
if __name__ == '__main__':
function_1()
function_2()
Если ваш файл YAML выглядит следующим образом:
example: file
very: simple
, вывод вышеуказанной программы будетбыть:
master_def: {'example': 'file', 'very': 'simple'}