Introducing metaprogramming in Python. Understand type, \ _ \ _ new \ _ \ _, \ _ \ _ metaclass \ _ \ _ in understanding metaprogramming Since it is necessary, I will introduce it separately in blocks
To understand metaprogramming in Python first You have to understand that the class definition was an instance of type.
The following is the same behavior in the definition of normal class and type class.
class Hoge(object):
def function1(self, args):
return args
def function2(self, args):
return args + 50
def func1(self, args):
return args
def func2(self, args):
return args + 50
# type(Class name, parent class, member attributes)Will be
Hoge = type('Hoge', (object, ), {'function1': func1, 'function2': func2})
As you can see from the above, the class definition was actually an instance of type. type (Hoge) returns type and isinstance (Hoge, type) returns True.
When creating an instance in Python, \ _ \ _ init \ _ \ _ is called and the instance is initialized. As you can see, there is an implicit \ _ \ _ new \ _ \ _ process before \ _ \ _ init \ _ \ _. In this \ _ \ _ new \ _ \ _, the above type is automatically instantiated and the class is defined.
I explained above that type is instantiated in \ _ \ _ new \ _ \ _, You can replace the instantiation of this type with another definition. That will be \ _ \ _ metaclass \ _ \ _. You can extend a class when instantiating a type by defining a function or class in \ _ \ _ metaclass \ _ \ _
class HogeMeta(type):
def __new__(mcs, name, bases, dictionary):
cls = type.__new__(mcs, name, bases, dictionary)
setattr(cls, 'member1', 10)
setattr(cls, 'member2', 20)
return cls
class Hoge(object):
__metaclass__ = HogeMeta
print Hoge().member1 -> 10
print Hoge().member2 -> 20
Manage multiple Skill class definitions with Meta class, When getting an arbitrary class with skill_key.
class AttackSkill(object):
name = u'Oversized attack'
class HealSkill(object):
name = u'recovery'
class PoisonSkill(object):
name = u'Poison attack'
class SkillMeta(type):
def __new__(mcs, name, bases, dictionary):
cls = type.__new__(mcs, name, bases, dictionary)
skills = {'attack': AttackSkill,
'heal': HealSkill,
'poison': PoisonSkill}
cls.SKILLS = skills
return cls
class Skills(object):
__metaclass__ = SkillMeta
SKILLS = {}
@classmethod
def get(cls, skill_key):
return cls.SKILLS[skill_key]
Skill = Skills.get
print Skill('attack').name ->Oversized attack
print Skill('heal').name ->recovery
The sample method can be done by combining functions and dicts without using Meta programming. The former is more extensible and can be written concisely. Also, since everything is completed in the class, it is highly object-oriented.
http://www.yunabe.jp/docs/python_metaclass.html
Recommended Posts