python - 动态定义类的 __init__ 参数(使用先前定义的字典)
问题描述
有没有办法使用字典来定义类的参数?
例如,假设我有一个包含一堆键值对的字典。每个键都应该是类的一个参数,每个值应该是该参数的默认值。
在代码方面,我正在寻找这样的东西:
d = {'apples':0,'bananas':1}
class A:
def __init__(self,k=v for k,v in d.items())
print('apples',apples)
print('bananas',bananas)
A(4)
应该输出:
-> apples 4
-> bananas 1
解决方案
您询问:
有没有办法使用字典来定义类的参数?
确实是这样。动态构建类通常使用所谓的元类来完成,即实例是其他类的类。
下面是一个做你想做的事的例子。除了__init__()
使用字典定义类的方法的参数外,它还生成方法的主体,该主体仅打印出其所有参数及其值。我添加了这个是因为你从来没有回答我在评论中问你是否想要完成这个问题。
简而言之,它的作用是生成定义函数所需的源代码,该函数具有所需的参数,然后是打印它们的代码行。完成后,使用内置exec()
函数执行代码以获得执行结果(即函数对象的可执行字节码)。"__init__"
最后,一个带有可执行字节码键和值的字典条目被添加到类的字典 ( classdict
) 中,然后将其传递给内置type()
函数以构造成可用class
对象。
呸!解释比代码更复杂。;¬)
class MyMetaClass(type):
def __new__(cls, name, bases, classdict, **kwargs):
initargs = classdict.pop('initargs', None)
if not initargs:
INIT_METHOD = f"def __init__(self):\n\tprint('{name}.__init__() called')\n"
else:
args = ", ".join(f"{k}={v}" for (k, v) in initargs.items())
body = "\n".join(f"\tprint({k!r}, {k})" for k in initargs.keys())
INIT_METHOD = (f'def __init__(self, ' + f'{args}' + '):\n'
f'\tprint("{name}.__init__() called")\n'
f'{body}\n')
result = {'__builtins__' : None, 'print': print} # Must explicitly list any builtins.
exec(INIT_METHOD, result)
init_method = result['__init__']
classdict.update({'__init__': init_method})
return type.__new__(cls, name, bases, classdict, **kwargs)
class A(metaclass=MyMetaClass):
initargs = {'apples': 0, 'bananas': 1}
A(4)
输出:
A.__init__() called
apples 4
bananas 1
推荐阅读
- r - 当 DF 在 R 中有 2 个相似的列名时选择 1 列
- plotly - Plotly Dash - 如何处理庞大的国家?
- cypress - 如何让赛普拉斯测试用例为非技术人员执行?
- android - Xamarin.Forms (AltBeacon Android Library) - 在后台检测到信标时发送本地通知
- android - Android 应用程序无法在真实设备上通过 NGROK 发送请求
- alibaba-cloud - 谁能帮我这个?阿里云 WA 中的 HTTPS
- inno-setup - Inno设置加载字符串,获取数字并添加
- django - Django-admin collectstatic 是一个未知命令
- html - 在 html src 中添加格式化的当前时间戳
- ruby-on-rails - NoMethodError:未定义的方法“wepay”用于#