是否可以在运行时向对象实例(不是类!)添加基类?关于Object#extend
在Ruby中的工作方式:
class Gentleman(object):
def introduce_self(self):
return "Hello, my name is %s" % self.name
class Person(object):
def __init__(self, name):
self.name = name
p = Person("John")
# how to implement this method?
extend(p, Gentleman)
p.introduce_self() # => "Hello, my name is John"
答案 0 :(得分:38)
这会动态定义一个新类GentlePerson
,并将p
的类重新分配给它:
class Gentleman(object):
def introduce_self(self):
return "Hello, my name is %s" % self.name
class Person(object):
def __init__(self, name):
self.name = name
p = Person("John")
p.__class__ = type('GentlePerson',(Person,Gentleman),{})
print(p.introduce_self())
# "Hello, my name is John"
根据您的请求,这会修改p
的基础,但不会更改p
的原始类Person
。因此,Person
的其他实例不受影响(如果AttributeError
被调用,则会引发introduce_self
。
虽然在问题中没有直接询问,但我会为googlers和好奇心寻求者添加,只有当类不直接从{{1}继承时,才可以动态更改类的基础但是(AFAIK) }}:
object
答案 1 :(得分:10)
稍微清洁的版本:
def extend_instance(obj, cls):
"""Apply mixins to a class instance after creation"""
base_cls = obj.__class__
base_cls_name = obj.__class__.__name__
obj.__class__ = type(base_cls_name, (base_cls, cls),{})
答案 2 :(得分:5)
虽然已经回答了,但这是一个功能:
def extend(instance, new_class):
instance.__class__ = type(
'%s_extended_with_%s' % (instance.__class__.__name__, new_class.__name__),
(instance.__class__, new_class),
{},
)