Python 被 @staticmethod 装饰的方法在调用时,会调用 __init__ 方法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
AbcHiyi
V2EX    Python

Python 被 @staticmethod 装饰的方法在调用时,会调用 __init__ 方法?

  •  
  •   AbcHiyi 2020-11-10 21:43:53 +08:00 3315 次点击
    这是一个创建于 1863 天前的主题,其中的信息可能已经有所发展或是发生改变。

    被测试代码入如下:

    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_'代码块?? 让人感觉就像是其中的代码被执行了一样

    23 条回复    2020-11-23 16:16:22 +08:00
    AbcHiyi
        1
    AbcHiyi  
    OP
       2020-11-10 21:49:21 +08:00
    顺道问一句,V2ex 怎么插入图片。刚刚加入这边还不清楚怎么操作。还是说能使用 markdown 语法来引用网图吗?
    singerll
        2
    singerll  
       2020-11-10 21:52:23 +08:00 via Android
    构造函数吧,虽然我不是程序员,大概也知道这个
    AbcHiyi
        3
    AbcHiyi  
    OP
       2020-11-10 22:21:50 +08:00
    @singerll 是啊 ,按道理来说不应该调用构造函数的。但是调试的时候,调用静态方法总是会从静态方法进去就很奇怪
    GodFastion
        4
    GodFastion  
       2020-11-10 22:30:06 +08:00 via Android
    如果不调用其他函数 __init__会默认执行
    mywaiting
        5
    mywaiting  
       2020-11-10 22:31:09 +08:00   1
    盲猜 self.b = B() 这句重载了 def b() 导致的问题???
    chashao
        6
    chashao  
       2020-11-10 22:32:19 +08:00
    我用 pycharm 试了试,不会进__init__
    Wincer
        7
    Wincer  
       2020-11-10 22:33:29 +08:00
    你在 *1 处初始化了 Config 的实例:setting.Config(self.save_dir),自然会进入 __init__ 内部
    mrchi
        8
    mrchi  
       2020-11-10 23:09:44 +08:00   1
    @Wincer 确实,不过楼主也说了,问题在于*2 处的方法也会跳转 init 。


    @AbcHiyi 会不会是 vscode debug 的问题,尝试直接执行呢
    Kvip
        9
    Kvip  
       2020-11-10 23:18:04 +08:00   1
    看了你的描述,我觉得很奇怪,
    我用 pycharm 实测执行了 A.b()后,输出的是`A.b method`,
    输出正常,和你输出的`b method`不一致
    AbcHiyi
        10
    AbcHiyi  
    OP
       2020-11-11 01:19:32 +08:00
    @GodFastion 这个我清楚,问题是 2 处的代码调用静态方法也触发了 init 构造函数
    AbcHiyi
        11
    AbcHiyi  
    OP
       2020-11-11 01:20:25 +08:00
    @Wincer 问题是在 2 处也会在 debug 时进入
    AbcHiyi
        12
    AbcHiyi  
    OP
       2020-11-11 01:21:52 +08:00
    @chashao @chashao 也许是 vscode 的 Python 插件的调试 bug
    AbcHiyi
        13
    AbcHiyi  
    OP
       2020-11-11 01:24:07 +08:00
    @mrchi 直接执行的话,2 处的代码是不会有动作的。主要的问题是不清楚是调试器的 bug 还是 python 本身的问题。
    AbcHiyi
        14
    AbcHiyi  
    OP
       2020-11-11 01:28:58 +08:00
    @GodFastion 请问以下具体是怎么回事呢?嗯按照我的理解的是在调用静态方法时,构造方法不应该被调用啊。如果默认被调用的话就需要重新设计代码了.
    AbcHiyi
        15
    AbcHiyi  
    OP
       2020-11-11 01:30:22 +08:00
    也许我应该换个 ide 试试
    metamask
        16
    metamask  
       2020-11-11 01:57:04 +08:00   1
    @AbcHiyi #14

    哈哈哈,老哥,上个贴你都还没回最后是怎样,又来新的

    不确定是不是你这句引起的
    cOnfig= setting.Config(self.save_dir)

    你干脆打多几个 print
    在 config 前后写,
    然后在 init 里面 print save_dir 的值和做个标记
    metamask
        17
    metamask  
       2020-11-11 02:00:01 +08:00   1
    因为有一种可能操作,

    你没在 save_ini 里面打断点或者 print,
    所以执行完这一条,他直接跳到下一条进入 init 。
    js8510
        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.
    js8510
        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.
    AbcHiyi
        20
    AbcHiyi  
    OP
       2020-11-11 08:31:58 +08:00
    @freakxx 哈哈 东西整越大,已经有点控制不住了。以及找到问题了,在别的模块中引入了然后在测试中就造成了这个现象,无意间在终端导入时发现打印的的东西不太对找到的
    AbcHiyi
        21
    AbcHiyi  
    OP
       2020-11-11 08:32:37 +08:00
    结案了,粗心大意,造成的哈哈哈
    metamask
        22
    metamask  
       2020-11-11 14:03:18 +08:00
    @AbcHiyi #20

    哈哈哈,不过我看你两次代码,感觉你这样写 python 爆炸概率很高,

    比如像你在 init 做的操作
    拆出来比较好,

    init 直接定义路径,不做一些操作。
    再定义一个子函数,在用的时候,再进行判断,没有的话再 update 。

    -----------------

    不过我很喜欢你的贴,总有一些弯弯绕绕让我尝试领会另一种奇特姿势。
    AbcHiyi
        23
    AbcHiyi  
    OP
       2020-11-23 16:16:22 +08:00
    @freakxx 哈哈喜欢尝试一些新姿势,挺有趣的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5236 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 09:02 PVG 17:02 LAX 01:02 JFK 04:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86