2014-09-21 4 views
0

Для предыдущих версий вопроса см revision history - удалось придумать минимальный исполняемый пример, который воспроизводит проблемуКак установить атрибут класса из метода экземпляра в python?

# 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) 

Run test.py и введите имя 123 в приглашении увидеть ноны отпечатанные. Ну, может быть, это что-то очевидно - это было часов :)

EDIT: Для репродуктора публикуемую здесь это:

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

работы. Однако добавление from sync import Sync (и вариантов) в моем основном не помогло. Я, наконец, «решить» его:

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 не работает.

НАКОНЕЦ: спасибо к comment по @MartijnPieters:

# module watcher.sync 

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

это выглядит некрасиво, хотя так не стесняйтесь комментировать (или даже добавить ответ) о том, как я мог бы избежать.

+1

У вас есть опечатка. Ваш метод init называется int вместо init. – Reeling

+1

Ваш новый пример включает в себя множество других осложнений. Как вы используете эти классы? – BrenBarn

+0

Я не вижу экземпляр 'Sync', который когда-либо создавался в вашем новом коде. –

ответ

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

+0

Ну, это правда - в моем реальном классе не ошиблись '__init__', хотя - позвольте мне посмотреть минута –

+1

@Mr_and_Mrs_D: вы ошиблись * что-то *; см. мою демонстрацию (с сеанса 2.7.8). –

+0

Я отредактировал вопрос с моим исходным кодом - будет продолжать смотреть, но я надеюсь, что вы видите то, что я не делаю :) –

Смежные вопросы