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

发布于 2021-01-29 15:09:29

是否可以在运行时将基类添加到对象实例(而不是类!)?沿着怎样的路线的东西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
被浏览
81
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这动态地定义了一个新类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
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看