2017-03-15 12 views
1

私はコマンドライン引数として2つのユーザー入力を取得するPythonスクリプトを持っています。最初のユーザー入力はload-classとなり、2番目のユーザー入力はcall-methodとなります。Pythonでクラスと呼び出しメソッドを動的にロードする方法は?

メインのPythonスクリプトは、他のものをロードしてコントローラケースと呼ばれるPythonスクリプトをロードし、それらのスクリプト内のメソッドを呼び出し、メソッドで何かを返します。これは、オペレータがコントローラケースのPythonスクリプトを直接実行することができない理由です。

#!/usr/bin/env python 

import os 
for module in os.listdir(os.path.dirname(__file__)): 
    if module == '__init__.py' or module[-3:] != '.py': 
     continue 
    __import__(module[:-3], locals(), globals()) 
del module 
:私は __init__.pyを持って ControllerCasesフォルダ内

#!/usr/bin/env python 

class dummy(): 
    def hello(argv): 
     print 'Hello World' 

#!/usr/bin/env python 

import sys 
import argparse 
import textwrap 

import ControllerCases 

parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter, 
    epilog="{0}".format('-' * 80), 
    description=textwrap.dedent('''\ 
    TODO: Enter Title Here 
{0} 
    TODO: Enter Info Here 
{0} 
'''.format('-' * 80)) 
) 

parser.add_argument('--load-class', '-c', type=str, required=True, help="Name of the class.") 
parser.add_argument('--call-method', '-m', type=str, required=True, help="Name of the method within selected class.") 

parsed_args = parser.parse_args() 

def main(argv): 
    print 'Number of arguments:', len(sys.argv), 'arguments.' 
    print 'Argument List:', str(sys.argv) 
    print 'Load class: ', str(parsed_args.load_class) 
    print 'Call method: ', str(parsed_args.call_method) 
    getattr(ControllerCases[parsed_args.load_class], parsed_args.call_method)(argv) 

if __name__ == "__main__": 
    main(sys.argv[1:]) 

コントローラの例のように見ているPythonスクリプト:ここ

は非稼働例です

今コントローラを実行しようとしましたが、 ned:

$ python controller.py --load-class dummy --call-method hello 
Number of arguments: 5 arguments. 
Argument List: ['controller.py', '--load-class', 'dummy', '--call-method', 'hello'] 
Load class: dummy 
Call method: hello 
Traceback (most recent call last): 
    File "controller.py", line 33, in <module> 
    main(sys.argv[1:]) 
    File "controller.py", line 30, in main 
    getattr(ControllerCases[parsed_args.load_class], parsed_args.call_method)(argv) 
TypeError: 'module' object has no attribute '__getitem__' 

私はPython 2.7.13を使用しています。

Pythonでクラスと呼び出しメソッドを動的にロードする方法はありますか?

答えて

1

実生活の助けを借りて解決しました。コントローラケースをクラスからモジュールに変換しなければならず、getattrを2回呼び出す必要がありました。モジュールに対して1回、メソッドに対して1回。


class XYZ():線を除去することによってコントローラケースモジュールにコントローラケースクラスを変換します。

#!/usr/bin/env python 

class dummy(): 
    def hello(argv): 
     print 'Hello World' 

に:より

#!/usr/bin/env python 

def hello(argv): 
    print 'Hello World' 

変更コントローラgetattrコード。

から:

def main(argv): 
    print 'Number of arguments:', len(sys.argv), 'arguments.' 
    print 'Argument List:', str(sys.argv) 
    print 'Load class: ', str(parsed_args.load_class) 
    print 'Call method: ', str(parsed_args.call_method) 
    getattr(ControllerCases[parsed_args.load_class], parsed_args.call_method)(argv) 

if __name__ == "__main__": 
    main(sys.argv[1:]) 

へ:

def main(argv): 
    print 'Number of arguments:', len(sys.argv), 'arguments.' 
    print 'Argument List:', str(sys.argv) 
    print 'Load class: ', str(parsed_args.load_class) 
    print 'Call method: ', str(parsed_args.call_method) 
    load_class = getattr(ControllerCases, parsed_args.load_class) 
    call_method = getattr(load_class, parsed_args.call_method) 
    try: 
     call_method(argv) 
    except KeyboardInterrupt: 
     print 'UserAborted' 

if __name__ == "__main__": 
    main(sys.argv[1:]) 
関連する問題