python的with语句与yaml使用

with语句 

import yaml
from experiment import ExperimentStage

if __name__ == '__main__':

    with open('./configs/common.yaml', 'r') as f:
        common_config = yaml.load(f, Loader=yaml.Loader)
        print(type(common_config))
        print(common_config)
        if not isinstance(common_config['device'], list):
            common_config['device'] = [common_config['device']]

    experiment_configs = []
    # for experiment_path in args['experiments']:
    experiment_path='./configs/basis_exp/experiment_fedstil.yaml'
    with open(experiment_path, 'r') as f:
        exp_config = dict(common_config['defaults'])
        exp_config.update(yaml.load(f, Loader=yaml.Loader))
        experiment_configs.append(exp_config)

    with ExperimentStage(common_config, experiment_configs) as exp_stage:
        exp_stage.run()
class ExperimentStage(object):

    def __init__(self, common_config: Dict, exp_configs: Union[Dict, Tuple[Dict]]):
        self.common_config = common_config
        self.exp_configs = [exp_configs] if isinstance(exp_configs, Dict) else exp_configs
        self.logger = Logger('stage')
        self.container = VirtualContainer(self.common_config['device'], self.common_config['parallel'])

    def __enter__(self):
        self.check_environment()
        return self

    def __exit__(self, type, value, trace):
        if type is not None and issubclass(type, Exception):
            self.logger.error(value)
            raise trace
        return self

    def check_environment(self):
        # check runtime device
        devices = self.common_config['device']
        for device in devices:
            try:
                torch.Tensor([0]).to(device)
            except Exception as ex:
                self.logger.error(f'Not available for given device {device}:{ex}')
                exit(1)

        # check dataset base path
        datasets_dir = self.common_config['datasets_dir']
        if not os.path.exists(datasets_dir):
            self.logger.error(f'Datasets base directory could not be found with {datasets_dir}.')
            exit(1)

        # check dataset base path
        checkpoints_dir = self.common_config['checkpoints_dir']
        if os.path.exists(checkpoints_dir):
            self.logger.warn(f'Checkpoint directory {checkpoints_dir} is not empty.')

        self.logger.info('Experiment stage build success.')

对于上面这个代码,我不理解的是with的使用与yaml文件是怎样读取,怎样编写的。

参考文章:

Python with理解

Python----魔法函数__enter__/__exit__的用法

上面这段代码中with用于读取文件common.yaml与experiment_fedstil.yaml

在平时读取文件的时候我会这样读取:

file = open("/tmp/foo.txt")
data = file.read()
file.close()

这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。

因此使用with更好:

with open("/tmp/foo.txt") as file:
    data = file.read()

__enter__与__exit__

与with语句配套的是__enter__与__exit__,在执行with语句之前,先实例化ExperimentStage类,运行init方法,然后运行__enter__方法,将__enter__的返回值赋值给as后面的变量,接着运行with-as后面的语句,运行完之后,最后运行__exit__方法。

yaml的读取,写入

参考文章:

python yaml用法详解

YAML是一种直观的能够被电脑识别的的数据序列化格式,容易被人类阅读,并且容易和脚本语言交互。YAML类似于XML,但是语法比XML简单得多,对于转化成数组或可以hash的数据时是很简单有效的。

读取:

import yaml

if __name__ == '__main__':

    with open('test.yaml', 'r') as f:
        common_config = yaml.load(f, Loader=yaml.Loader)
        print(type(common_config))
        print(common_config)

test.yaml

name: Tom Smith
age: 37
spouse:
    name: Jane Smith
    age: 25
children:
 - name: Jimmy Smith
   age: 15
 - name1: Jenny Smith
   age1: 12

运行结果:


{'name': 'Tom Smith', 'age': 37, 'spouse': {'name': 'Jane Smith', 'age': 25}, 'children': [{'name': 'Jimmy Smith', 'age': 15}, {'name1': 'Jenny Smith', 'age1': 12}]}

children这里是列表: 

yaml语法:

1. 大小写敏感

2. 使用缩进表示层级关系

3. 缩进时不允许使用Tab,只允许使用空格

4. 缩进的空格数目不重要,只要相同层级的元素左对齐即可

5. # 表示注释,从它开始到行尾都被忽

2、yaml转字典

python的with语句与yaml使用_第1张图片

python的with语句与yaml使用_第2张图片

3、yaml转列表

python的with语句与yaml使用_第3张图片

python的with语句与yaml使用_第4张图片

4、如果字符串没有空格或特殊字符,不需要加引号,但如果其中有空格或特殊字符,则需要加引号了

保存:

import yaml
aproject = {'name': 'Silenthand Olleander',
            'race': 'Human',
            'traits': ['ONE_HAND', 'ONE_EYE']
            }
with open('test.yaml', 'w') as f:
    yaml.dump(aproject,f)

python的with语句与yaml使用_第5张图片

你可能感兴趣的:(做一个完整项目,学习,python)