__init__
オブジェクトに渡される引数をオブジェクト属性として設定するメタクラスをPython(2.7)で作成しようとしています。
class AttributeInitType(type):
def __call__(self, *args, **kwargs):
obj = super(AttributeInitType, self).__call__(*args, **kwargs)
for k, v in kwargs.items():
setattr(obj, k, v)
return obj
使用法:
class Human(object):
__metaclass__ = AttributeInitType
def __init__(self, height=160, age=0, eyes="brown", sex="male"):
pass
man = Human()
質問:man
インスタンスにクラスののようにデフォルトの属性を設定させたいのですが__init__
。どうすればいいですか?
更新:私はさらに良い解決策に到達しました:
__init__
クラスの作成中にメソッドを1回だけ検査します- クラスの実数によって(おそらく)設定された属性をオーバーライドしません
__init__
コードは次のとおりです。
import inspect
import copy
class AttributeInitType(type):
"""Converts keyword attributes of the init to object attributes"""
def __new__(mcs, name, bases, d):
# Cache __init__ defaults on a class-level
argspec = inspect.getargspec(d["__init__"])
init_defaults = dict(zip(argspec.args[-len(argspec.defaults):], argspec.defaults))
cls = super(AttributeInitType, mcs).__new__(mcs, name, bases, d)
cls.__init_defaults = init_defaults
return cls
def __call__(mcs, *args, **kwargs):
obj = super(AttributeInitType, mcs).__call__(*args, **kwargs)
the_kwargs = copy.copy(obj.__class__.__init_defaults)
the_kwargs.update(kwargs)
for k, v in the_kwargs.items():
# Don't override attributes set by real __init__
if not hasattr(obj, k):
setattr(obj, k, v)
return obj