引数を使用してクラスのインスタンスを作成しようとしていますが、問題は、クラス作成の基本を決定するためにメタ クラスに位置引数が必要なことです。
これをさらにクリアする例を次に示します。
クラスのメソッドになる子は次のとおりです(親クラスのオブジェクト名として選択されます)
import inspect
import sys
class ParentA:
pass
class Child1(ParentA):
def ch1_cmd(self):
print('This is RAM Telnet IOS Cisco ')
class Child2(ParentA):
def ch2_cmd(self):
print('This is Time Telnet IOS Cisco ')
ここに、ディクショナリである追加の引数CONNECTION_TYPEを受け入れるメタクラスがあるため、メタクラスはこのディクショナリに従って適切な子をロードします
class MainMeta(type):
def __new__(cls, clsname, bases, clsdict, CONNECTION_TYPE):
if CONNECTION_TYPE != None:
CONNECTION_TYPE['OBJ'] = getattr(
sys.modules[__name__], CONNECTION_TYPE['OBJ'])
if CONNECTION_TYPE['TYPE'] == 'CONDITION1':
if CONNECTION_TYPE['CONNECTION_TYPE'] == 'CONDITION2':
bases = []
for name, obj in inspect.getmembers(sys.modules[__name__]):
if inspect.isclass(obj):
if CONNECTION_TYPE['OBJ'].__subclasscheck__(obj):
if CONNECTION_TYPE['OBJ'].__name__ != obj.__name__:
bases.append(obj)
bases = tuple(bases)
print(clsname, bases, clsdict) # here Shows that bases are loaded CORRECTLY
return super().__new__(cls, clsname, bases, clsdict)
これは、メタ クラスに提供されるディクショナリです。
clsdic = {'TYPE': 'CONDITION1',
'CONNECTION_TYPE': 'CONDITION2', 'OBJ': "ParentA", }
ここに問題があります。exec を使用して、目的のCONNECTION_TYPE辞書でクラスを動的に作成します。コードは Err なしで実行されますが、作成されたクラスには何かが欠けています。__module__
def dev_creator(*args, **kwargs):
print()
myclass = f"""class MyMain(metaclass=MainMeta, CONNECTION_TYPE={kwargs}):\n pass\n"""
return exec(myclass, globals())
dev = dev_creator(**clsdic)
print(dir(dev))
これは出力です:|
MyMain (<class '__main__.Child1'>, <class '__main__.Child2'>) {'__module__': '__main__', '__qualname__': 'MyMain'}
['__bool__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']