动态地将基类混入Python中的实例 [英] Dynamically mixin a base class to an instance in Python
问题描述
是否可以在运行时将基类添加到对象实例(不是类!)? Object#extend
在Ruby中的工作原理:
Is it possible to add a base class to an object instance (not a class!) at runtime? Something along the lines of how Object#extend
works in 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"
推荐答案
这动态定义了一个新的类GentlePerson
,并为它重新分配了p
的类:
This dynamically defines a new class GentlePerson
, and reassigns p
's class to it:
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
的其他实例不受影响(如果调用introduce_self
,则会引发AttributeError
).
Per your request, this modifies p
's bases, but does not alter p
's original class Person
. Thus, other instances of Person
are unaffected (and would raise an AttributeError
if introduce_self
were called).
尽管在问题中并未直接询问,但我将为Googlers和好奇心求助者补充说,也可以动态更改类的基础,但是(AFAIK)仅在该类不直接继承自object
的情况下:
Although it was not directly asked in the question, I'll add for googlers and curiosity seekers, that it is also possible to dynamically change a class's bases but (AFAIK) only if the class does not inherit directly from object
:
class Gentleman(object):
def introduce_self(self):
return "Hello, my name is %s" % self.name
class Base(object):pass
class Person(Base):
def __init__(self, name):
self.name = name
p = Person("John")
Person.__bases__=(Gentleman,object,)
print(p.introduce_self())
# "Hello, my name is John"
q = Person("Pete")
print(q.introduce_self())
# Hello, my name is Pete
这篇关于动态地将基类混入Python中的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!