
被测试代码入如下:
class Config: def __init__(self, save_path=False, file_name="config.ini"): if save_path: try: self.tgt_lang = self.read_inf(file_name, save_path) except errors.FileError: self.tgt_lang = update_language_code() self.save_ini(file_name, save_path, self.tgt_lang) else: self.tgt_lang = update_language_code() @ staticmethod @ file_check def read_inf(file_name, path): """读取配置文件""" c_p = ConfigParser() c_p.read(os.path.join(file_name, path), encoding='UTF-8') return {i: dict(c_p.items(i)) for i in c_p.sections()} @ staticmethod def save_ini(file_name, path, data): """保存配置文件""" c_p = ConfigParser() c_p.read(path, encoding='UTF-8') for section in data.keys(): for option in data_table[section].keys(): try: c_p.set(section, option, data_table[section][option]) except NoSectionError: c_p.add_section(section) c_p.set(section, option, data_table[section][option]) path = Path(path) if not path.is_dir(): path.mkdir() full_path = os.path.join(path, file_name) with open(full_path, 'w', encoding='UTF-8') as file: c_p.write(file) 这边是测试代码:
class Config(unittest.TestCase): def setUp(self): self.save_dir = os.path.join(BASE_DIR, 'test_files') def tearDown(self): # 清扫文件 try: shutil.rmtree(self.save_dir) except FileNotFoundError: pass def test_read_config(self): *1 setting.Config(self.save_dir) *2 setting.Config.save_ini( 'config.ini', self.save_dir, { "test": {'test-check': 'True'} } ) cOnfig= setting.Config(self.save_dir) if 'test' not in config.tgt_lang: self.fail('未能从本地文件读取数据') 主要问题是,在测试时,我在*1 和*2 的位置打了断点,并在被测类的'_init_' 方法内打了断点。 发现在调用*2 处的静态方法时,vscode 会跳转到被测类的'_init_'方法中. 我就纳闷了,怎么调用静态方法还会调用'_init_'方法,这不应该啊.
update_language_code()这个函数下载数据挺耗时间的,都是尽量能保存到本地就使用配置文件中的数据,不行再从服务器中下载
下面的代码是一个简化之后的样子,
class B: def __init__(selsf): print('b class') class A: def __init__(self): print('a class') self.b = B() @staticmethod def b(): print("A.b method") 在单独初始化'A 时'
A() 控制台打印
a class b class 在调用静态方法 A.b 时
A.b() 控制台打印
b method 这让我更迷惑了,这和我设想的时一样的。但是 vscode 调试代码时为什么还是会跳转到'_init_'代码块?? 让人感觉就像是其中的代码被执行了一样
1 AbcHiyi OP 顺道问一句,V2ex 怎么插入图片。刚刚加入这边还不清楚怎么操作。还是说能使用 markdown 语法来引用网图吗? |
2 singerll 2020-11-10 21:52:23 +08:00 via Android 构造函数吧,虽然我不是程序员,大概也知道这个 |
4 GodFastion 2020-11-10 22:30:06 +08:00 via Android 如果不调用其他函数 __init__会默认执行 |
5 mywaiting 2020-11-10 22:31:09 +08:00 盲猜 self.b = B() 这句重载了 def b() 导致的问题??? |
6 chashao 2020-11-10 22:32:19 +08:00 我用 pycharm 试了试,不会进__init__ |
7 Wincer 2020-11-10 22:33:29 +08:00 你在 *1 处初始化了 Config 的实例:setting.Config(self.save_dir),自然会进入 __init__ 内部 |
8 mrchi 2020-11-10 23:09:44 +08:00 |
9 Kvip 2020-11-10 23:18:04 +08:00 看了你的描述,我觉得很奇怪, 我用 pycharm 实测执行了 A.b()后,输出的是`A.b method`, 输出正常,和你输出的`b method`不一致 |
10 AbcHiyi OP @GodFastion 这个我清楚,问题是 2 处的代码调用静态方法也触发了 init 构造函数 |
13 AbcHiyi OP @mrchi 直接执行的话,2 处的代码是不会有动作的。主要的问题是不清楚是调试器的 bug 还是 python 本身的问题。 |
14 AbcHiyi OP @GodFastion 请问以下具体是怎么回事呢?嗯按照我的理解的是在调用静态方法时,构造方法不应该被调用啊。如果默认被调用的话就需要重新设计代码了. |
15 AbcHiyi OP 也许我应该换个 ide 试试 |
16 @AbcHiyi #14 哈哈哈,老哥,上个贴你都还没回最后是怎样,又来新的 不确定是不是你这句引起的 cOnfig= setting.Config(self.save_dir) 你干脆打多几个 print 在 config 前后写, 然后在 init 里面 print save_dir 的值和做个标记 |
17 metamask 2020-11-11 02:00:01 +08:00 因为有一种可能操作, 你没在 save_ini 里面打断点或者 print, 所以执行完这一条,他直接跳到下一条进入 init 。 |
18 js8510 2020-11-11 06:06:32 +08:00 check type of `setting.Config` to see if it's a instance or a class. |
19 js8510 2020-11-11 06:09:43 +08:00 also, you need to make sure that there is no reference to any Config instance inside the `save_ini ` function. |
20 AbcHiyi OP @freakxx 哈哈 东西整越大,已经有点控制不住了。以及找到问题了,在别的模块中引入了然后在测试中就造成了这个现象,无意间在终端导入时发现打印的的东西不太对找到的 |
21 AbcHiyi OP 结案了,粗心大意,造成的哈哈哈 |