一尘不染

动态将基类混入Python中的实例

python

是否可以在运行时将基类添加到对象实例(而不是类!)?沿着怎样的路线的东西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"

阅读 137

收藏
2021-01-20

共1个答案

一尘不染

这动态地定义了一个新类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不受影响(并且会引发AttributeErrorifintroduce_self的调用)。


尽管没有在问题中直接提出要求,但我将为Googlers和好奇心求助者补充说,也可以动态更改类的基础,但前提是(AFAIK)仅当该类不直接继承自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
2021-01-20