如何在python中从实例方法设置类属性?

时间:2014-09-21 20:34:08

标签: python python-2.7 python-import

对于问题的先前版本,请参阅revision history - 设法提出一个可重现问题的最小可执行示例

# module test.py
import shlex
from test2 import Parser

class Test(object):
    sync_client = None

    def __init__(self):
        self.__class__.sync_client = 1
        parser = Parser(description='desc') # was before the assignment - egal
        while True:
            cmd = shlex.split(raw_input('> ').strip())
            parser.parse_args(cmd)

    @classmethod
    def newRequestClient(cls):
        print cls.sync_client # None

if __name__ == "__main__":
    Test()

# module test2.py
import argparse

class Share(object):
    class _ShareAction(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            from test import Test
            print Test.sync_client # None
            Test.newRequestClient()

    def __call__(self, subparsers):
        parser_a = subparsers.add_parser('name')
        parser_a.add_argument(dest='dest', help='help2',
                              action=Share._ShareAction)

class Parser(argparse.ArgumentParser):
    def __init__(self, description, add_h=True):
        super(Parser, self).__init__(description=description, add_help=add_h)
        subparsers = self.add_subparsers(title='Commands')
        subparsers._parser_class = argparse.ArgumentParser
        Share()(subparsers)

在提示符下运行test.py并输入名称123,以查看打印的Nones。好吧也许这是显而易见的事情 - 它已经过了几个小时:)

编辑:对于此处发布的重现器:

if __name__ == "__main__":
    from test import Test
    Test()

的工作原理。然而,在我的主要内容中添加from sync import Sync(和变体)并没有帮助。我终于"解决了#34;它由:

class Share(Command):
    class _ShareAction(argparse.Action):
        def __call__(self, parser, namespace, values, option_string=None):
            sync = sys.modules['__main__']
            print sync.Sync.sync_client # <SyncClient(SyncClient, started 6084)>
            sync.Sync.newRequestClient(host=namespace.host, repo=values)

但我还不完全理解为什么from sync import Sync不起作用。

最终:感谢@MartijnPieters的comment

# module watcher.sync

if __name__ == "__main__":
    from watcher.sync import Sync
    Sync().main()

这看起来很难看,但我可以随意评论(或者甚至添加答案)我是如何避免的。

1 个答案:

答案 0 :(得分:2)

你拼错了__init__

def __int__(self):

您错过了i,并且根本没有调用该方法。纠正错误并进行测试。

演示:

>>> class Test(object):
...     class_attr = None
...     def __init__(self):  # note the spelling
...         self.__class__.class_attr = 1
...     @staticmethod
...     def static_meth():
...         print Test.class_attr
...     @classmethod
...     def class_meth(cls):
...         print cls.class_attr
... 
>>> t = Test()
>>> Test.class_attr
1
>>> Test.static_meth()
1
>>> Test.class_meth()
1
>>> t.class_meth()
1
>>> t.static_meth()
1

在您更新的代码中,您有两个问题:

首先在设置类属性之前创建Parser 的实例。在调用self.__class__.sync_client = 1时,Parser.__init__行尚未执行。

然后混淆主脚本和test模块。 Python将主脚本导入为__main__而不是test 。如果将Test 移动到单独的模块,请使用from __main__ import Test,您的代码将起作用。

请参阅Importing modules: __main__ vs import as module