代码之家  ›  专栏  ›  技术社区  ›  Ivan Smirnov

如何让父类的类属性进入派生类的范围?

  •  -1
  • Ivan Smirnov  · 技术社区  · 8 年前

    我有一个类,它定义了多个类属性和多个方法。这些方法的默认参数等于类属性。有时属性是从方法中使用的(带有 self. 预先准备好的)。

    class MyClass:
        VAL1 = "hello"
        VAL2 = "world"
    
        def foo(self, x=VAL1, y=VAL2):
            if x == self.VAL1:
                print "yay"
    
        def bar(self, t=VAL2):
            pass
    

    现在,出于某种原因,我想将attributes声明移动到一个单独的类中,并在其子类中拆分方法。

    class Base:
        VAL1 = "hello"
        VAL2 = "world"
    
    class Derived1(Base):
        def foo(self, x=VAL1, y=VAL2):
            if x == self.VAL1:
                print "yay"
    
    class Derived2(Base):
        def bar(self, t=VAL2):
            pass
    

    然而,这不起作用,因为Base的参数VAL1和VAL2在派生类中超出了范围。

    现在重点是: 我无法更改方法的代码 *.那么显而易见的写作方式 def bar(self, t=Base.VAL2) 不起作用。

    有没有其他办法扩大范围?

    我正在使用Python 2.7。

    (*)这个类中有几十个方法,我不想太多地修改现有代码,因为在项目的其他地方也使用了类似的编码约定。如果你想争论,请把这个问题作为一个教育问题来考虑。

    1 回复  |  直到 8 年前
        1
  •  -1
  •   Oliver Evans pms    8 年前

    怎么样:

    class Base:
        VAL1 = "hello"
    
    class Derived1(Base):
        VAL1 = Base.VAL1
    
        def foo(self, x=VAL1):
            print(x)
    
    d = Derived1()
    d.foo()
    

    编辑: 我不确定它是否好看,但它更自动化,也许更适合你。

    import inspect
    
    class Base:
        VAL1 = "hello"
        VAL2 = "world"
    
    class Derived1(Base):
        for var, val in inspect.getmembers(Base):
            locals()[var] = val
    
        def foo(self, x=VAL1, y=VAL2):
            if x == self.VAL1:
                print "yay"
            if y == self.VAL2:
                print "hoorah!"
    
    d1 = Derived1()
    d1.foo()
    

    双重编辑:

    如果你不想复制 __doc__ 和 __module__ ,你可以用

    for var, val in inspect.getmembers(Base):
        if(var[:2] != '__'):
            locals()[var] = val
    

    据我所知,这在Python中并不常见,所以我猜大多数解决方案都会有点难看(但我很想看到一个反例!)