2012-04-14 24 views
1

我習慣在構造函數之前聲明類中的靜態字段/變量。在Python中這樣做會導致錯誤。如何在構造函數之前聲明靜態變量,以及如何在其正文中引用類?

下面是一個例子類:

class StringCompare: 

    methods = OrderedDict() 
    # ERROR!: 
    #methods['equals'] = equals 
    #methods['ends with'] = endswith 
    #methods['starts with'] = startswith 
    #methods['contains'] = contains 

    @staticmethod 
    def equals(a, b): 
     return a == b 

    @staticmethod 
    def contains(a, b): 
     return a.find(b) != -1 

    @staticmethod 
    def startswith(a, b): 
     return a.startswith(b) 

    @staticmethod 
    def endswith(a, b): 
     return a.endswith(b) 

    methods['equals'] = equals 
    methods['ends with'] = endswith 
    methods['starts with'] = startswith 
    methods['contains'] = contains 

是否有更優雅的方式(除了直接把所有語句全班後前綴來StringCompare.所訪問的每一VAR)?

這裏最好的做法是什麼?

class Type(InlineFragment): 

    # primitive types get None as package name 
    def __init__(self, packageName, name, genericType=None): 

     ... 

    def ... 

    primitive = { 
     'Character': Type(None, 'char'), 
     'Byte'  : Type(None, 'byte'), 
     'Short' : Type(None, 'short'), 
     'Integer' : Type(None, 'int'), 
     'Long'  : Type(None, 'long'), 
     'Boolean' : Type(None, 'boolean'), 
     'Float' : Type(None, 'float'), 
     'Double' : Type(None, 'double'), 
    } 

這將導致一個錯誤:試圖從同一個類中調用構造函數時


一個更復雜的情況是

\jpa_export_fragments.py", line 361, in Type 
    'Character' : Type(None, 'char'), 
NameError: name 'Type' is not defined 

這應該工作,但我只能通過將這些代碼放在課程之外來解決這個問題。

+2

雖然我試圖提供有用的例子,但答案是「Python是不同的,學習它的獨特風格」。在Python中,並非每件事都必須在一個類中。 'primatives'應該是'Type'定義後的模塊級變量。 – agf 2012-04-14 19:57:51

回答

3

一般來說,解決方案是使用class decorators。爲了您的例子,你可能想將其與類方法相結合:

def apply_method(attr): 
    def apply_to(cls): 
     setattr(cls, attr, getattr(cls, '_' + attr)()) 
     return cls 
    return apply_to 

@apply_method('primative') 
class Type(object): 

    def __init__(self, *args): 
     pass 

    @classmethod 
    def _primative(cls): 
     return { 
    'Character': cls(None, 'char'), 
    'Byte'  : cls(None, 'byte'), 
    'Short' : cls(None, 'short'), 
    'Integer' : cls(None, 'int'), 
    'Long'  : cls(None, 'long'), 
    'Boolean' : cls(None, 'boolean'), 
    'Float' : cls(None, 'float'), 
    'Double' : cls(None, 'double'), 
     } 

你的第一個例子看起來非常聯合國Python化,所以我毫不猶豫地提出了一個裝飾。相反,也許你想要一個str ing子類?

class StringCompare(str): 
    # none of these are any different from the normal string operations 
    # you would really only override ones that are different. 

    def __eq__(self, other): 
     return super(StringCompare, self).__eq__(other) 

    def __contains__(self, other): 
     return self.find(other) != -1 

    def startswith(self, other): 
     return super(StringCompare, self).startswith(other) 

    def endswith(self, other): 
     return super(StringCompare, self).endswith(other) 


print StringCompare('boogaloo').startswith('boo') # True 
相關問題