获取对类属性的访问权限

时间:2018-09-21 10:41:04

标签: python-2.7 class yaml

import yaml

class Import_Yaml_Setting():
    def __init__(self, path):
        self.read_yaml(path)

    def read_yaml(self, path):
        stream = open(path, 'r')
        self.settings = yaml.load(stream)
        stream.close()


class MasterDef(Import_Yaml_Setting):
    def __init__(self, path):
        Import_Yaml_Setting.__init__(self, path)


def function_1():
    path = 'path_to_settings\\yaml_file.yaml'

    MasterDef(path)


def function_2():
    MasterDef.settings


if __name__ == '__main__':
    function_1()
    function_2()

我的计划是要有一个类Import_Yaml_Setting,该类将从yaml文件导入设置。类MasterDef继承了类Import_Yaml_Setting。 在“ function_1”之后,调用MasterDef以导入设置。我想在程序中执行一次。之后,我只想访问导入的设置 无需再次导入它们。应该这样做function_2

我的问题

我不知道我该如何打MasterDef。如果我要创建一个MasterDef的实例,那么我将无法在function_2中访问该实例。

另外,我收到一条错误消息,指出MasterDef没有属性settings

什么是正确的方法?

1 个答案:

答案 0 :(得分:1)

有些事情不正确,所以让我们从最明显的事情开始。

如果您有一个类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()

以上几点注意事项:

  • 如果出于某种原因,您在Python 2.7上做任何新的事情 通过包括所示的master_def: {'some': 'setting'} 导入,使事情与Python3更加兼容。即使您只是使用 from __future__函数(而不是过时的print语句)。它 将使过渡更加容易(2020年将达到2.7停产)
  • 再次在2.7中将您的基类设为print的子类, 使它例如可能具有属性。
  • 通过测试objectmaster_def,您可以调用多个None

您还应该注意,PyYAML function_1如其内容所示 文档,如果您无法完全控制 您的输入。很少需要使用load,所以请使用load() 或升级到实现较新的YAML的ruamel.yaml程序包 1.2标准(2009年发布,因此没有使用PyYAML的借口 仍然不支持该功能。

由于您似乎也在Windows上(假设您使用safe_load()),请考虑使用原始字符串 使用\\在不需要转义反斜杠的地方。我要出去了 我的完整示例中的路径部分,因为我不在Windows上:

os.path.join()

如果您的YAML文件如下所示:

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()

以上程序的输出为:

example: file
very: simple