config_parser.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # -*- coding: utf-8 -*-
  2. # @Time : 2022/6/24 14:04
  3. # @Author : MaochengHu
  4. # @Email : wojiaohumaocheng@gmail.com
  5. # @File : config_parser.py
  6. # @Project : person_monitor
  7. import os
  8. import ast
  9. import sys
  10. import yaml
  11. import prettytable as pt
  12. from importlib import import_module
  13. from dev.src.utils.path_checker import check_file_exist
  14. from dev.src.utils.log import logger, SplitLine
  15. class Config(object):
  16. """
  17. This class is used for loading config from python script.
  18. """
  19. def __init__(self, config_path):
  20. check_file_exist(config_path)
  21. file_ext_name = os.path.splitext(config_path)[1]
  22. if file_ext_name == ".py":
  23. self.config_from_python_config(config_path)
  24. else:
  25. error_msg = "yolo config_files path is not exist -> {}".format(config_path)
  26. logger.error(error_msg)
  27. assert IOError(error_msg)
  28. def copy(self, new_config_dict: dict):
  29. """
  30. Copies this config_files into a new config_files object, making
  31. the changes given by new_config_dict.
  32. """
  33. ret = Config(vars(self))
  34. for key, val in new_config_dict.items():
  35. ret.__setattr__(key, val)
  36. return ret
  37. def replace(self, new_config_dict: dict):
  38. """
  39. Copies new_config_dict into this config_files object.
  40. Note: new_config_dict can also be a config_files object.
  41. """
  42. if isinstance(new_config_dict, Config):
  43. new_config_dict = vars(new_config_dict)
  44. for key, val in new_config_dict.items():
  45. self.__setattr__(key, val)
  46. def get(self, k, rv=None):
  47. """
  48. Get config file with key-value format
  49. :param k:
  50. :param rv:
  51. :return:
  52. """
  53. dict_v = self.__dict__.get(k, rv)
  54. return dict_v
  55. @staticmethod
  56. def _validate_py_syntax(filename):
  57. with open(filename, 'r', encoding='utf-8') as f:
  58. # Setting encoding explicitly to resolve coding issue on windows
  59. content = f.read()
  60. try:
  61. ast.parse(content)
  62. except SyntaxError as e:
  63. raise SyntaxError('There are syntax errors in config_files '
  64. 'file {}: {}'.format(filename, e))
  65. @staticmethod
  66. def _load_yaml(yaml_path: str):
  67. assert os.path.exists(yaml_path), "cannot find {}".format(yaml_path)
  68. with open(yaml_path, 'r', encoding='utf-8') as yaml_file:
  69. config = yaml.load(yaml_file, Loader=yaml.FullLoader)
  70. return config
  71. def config_from_yaml(self, yaml_path: str):
  72. """
  73. Get config file from yaml file
  74. :param yaml_path:
  75. """
  76. yaml_dict = self._load_yaml(yaml_path)
  77. self.config_from_dict(yaml_dict)
  78. def config_from_python_config(self, config_path):
  79. """
  80. Get config file from python file
  81. :param config_path:
  82. :return:
  83. """
  84. self._validate_py_syntax(config_path)
  85. python_name, extension = os.path.splitext(os.path.basename(config_path))
  86. # son_package = os.path.basename(os.path.dirname(__file__))
  87. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  88. mod = import_module("{}".format(python_name))
  89. del_module = ["os"]
  90. mod_dict = mod.__dict__
  91. for key in list(mod_dict.keys()):
  92. if "__" in key or key in del_module:
  93. del mod_dict[key]
  94. self.config_from_dict(mod_dict)
  95. def config_from_dict(self, insert_dict):
  96. """
  97. Get config file from dict
  98. :param insert_dict:
  99. """
  100. self.__dict__.update(insert_dict)
  101. def show_info(self, name=None):
  102. """
  103. Show Config file by config file dict
  104. :param name:
  105. """
  106. name = "Config" if name is None else name
  107. with SplitLine("{} Info".format(name), "-") as title_line:
  108. tb = pt.PrettyTable()
  109. tb.header_style = "title"
  110. tb.padding_width = 10
  111. tb.field_names = ["Parameters", "Values"]
  112. for key, value in self.__dict__.items():
  113. if key.startswith("__"):
  114. continue
  115. tb.add_row((str(key), str(value)))
  116. logger.info("\n{}\n".format(tb))
  117. def __call__(self, *args, **kwargs):
  118. pass
  119. def main():
  120. """
  121. test code
  122. """
  123. python_config_path = "../../develop/config_files/yolox_nano_bytetrack_tin.py"
  124. config = Config(python_config_path)
  125. config.show_info()
  126. if __name__ == "__main__":
  127. main()