2013-10-24 66 views
1

我不確定我是否正確地問這個問題,但我知道你們都足夠聰明,知道了:)。我在遇到幾個python類中的一些重複代碼時遇到了麻煩。這裏是我的意思的例子...Python類的繼承:動態屬性的創建

class Parent: 

    PATH_PROPERTIES = [ 'parent' ] 

    def __init__(self, path): 
     self.props = { 'parent': path } 

    def getPath(self): 
     return self.props['parent'] 


class Child(Parent): 

    PATH_PROPERTIES = [ 'child' ] 

    def __init__(self, path): 
     self.props = { 'child': path } 

    def getPath(self): 
     return self.props['child'] 

以上,是目前的情況,但我想通過做這樣的事情,以減少一些重複的...

class Parent: 
    name = 'parent' 

    PATH_PROPERTIES = [ name ] 

    def __init__(self, path): 
     self.props = (name: path) 

    def getPath(self): 
     return self.props[name] 

的最後一點代碼顯然不起作用。我無法找到任何能夠做C++的東西 - 就像宏一樣。什麼是壓縮此代碼的最佳方式?

+0

我很困惑。爲什麼你不使用標準類屬性(例如'Child.path'?) –

+5

是否有一個原因,你需要將標識符'parent''和''child''存儲爲字典鍵?更多的上下文會很有用。 – atomicinf

回答

2

你可以使用繼承:

class Parent: 

    PATH_PROPERTIES = [ 'parent' ] 

    def __init__(self, path): 
     self.props = { self.PATH_PROPERTIES[0]: path } 

    def getPath(self): 
     return self.props[self.PATH_PROPERTIES[0]] 


class Child(Parent): 

    PATH_PROPERTIES = [ 'child' ]  


c = Child('path') 
print(c.getPath()) 

打印

path 

注意的是Python通常優選使用property代替getter功能:

class Parent: 

    PATH_PROPERTIES = 'parent' 

    def __init__(self, path): 
     self.props = { self.PATH_PROPERTIES: path } 

    @property 
    def path(self): 
     return self.props[self.PATH_PROPERTIES] 


class Child(Parent): 

    PATH_PROPERTIES = 'child'   

c = Child('path') 
print(c.path) 

也打印

path 

注意c.path看起來像一個屬性的查找,但由於path是一個屬性,調用的功能飾以@property它。 語法看起來比c.getPath()好,但同樣給你提供相同的功能。有a decorator to make setters too

+0

請注意,如果所有將要執行的操作都是使用相同參數調用父類構造方法,則不需要在「Child」中包含「__init__」方法。 – Blckknght

+0

@Blckknght:你是對的;謝謝。 – unutbu

1

通常應該可以通過標準繼承來做到這一點,並重新設計一下(如unutbu的答案),但是您可以編寫一個工廠函數來創建類。這可能是最接近你在C++中用宏做的事情:

def make_class(name, base=object): 

    class Class(base): 

     PATH_PROPERTIES = [name] 

     def __init__(self, path): 
      self.props = {name: path} 

     @property 
     def path(self): 
      return self.props[name] 

    Class.__name__ = name.title() 
    return Class 

Parent = make_class("parent") 
Child = make_class("child", Parent)