2017-04-02 37 views
0
class A(object): 
    def __init__(self, val): 
     self.val = A.plus_one(val) 

    @staticmethod 
    def plus_one(val): 
     return val + 1 

我們可以在一個類中定義一個靜態方法,並在任何地方使用它。我的問題是,即使我們在這個類中使用這個靜態方法,爲什麼我們必須命名空間靜態方法,也就是在方法名稱前面添加A.爲什麼我們在Python中命名空間staticmethod?

我的想法是,我們可以簡單地改變機制,使類中的靜態方法名不必是命名空間爲:(儘管Python不現在支持它):

class A(object): 
    def __init__(self, val): 
     self.val = plus_one(val) 

    @staticmethod 
    def plus_one(val): 
     return val + 1 

我直覺是,因爲我們從班內呼喚,班級成員的優先級應高於全球職能,因此不會有任何含糊之處。爲什麼Python迫使我們命名空間呢?

+0

Python不強制它。你也可以定義一個「裸」的功能。但是使用靜態方法允許組織代碼的附加層。 – Keith

+0

@Keith我認爲你誤解了這個問題。這是關於調用靜態方法。 (我也很困惑。) –

+2

三個想法:1)你怎麼可能調用同名的頂級方法? 2)你還必須使用'self.member()'而不是隻調用'member()'。 3)即使靜態方法可以被重載,所以'self.plus_one'和'A.plus_one'之間可能存在差異。應該調用哪個? –

回答

1

類中定義的方法不能用裸名稱訪問,只能通過直接在類名稱空間中運行的代碼(不在另一個方法中)來運行。如果你想調用一個方法,你通常必須在某種對象(實例或類本身)上查找它。不同種類的方法在進行不同類型的查找時表現不同。

class Test(object): 
    def normal_method(self, foo): 
     print("normal_method", self, foo) 
     # none of the method names are valid here as bare names, only via self or Test 
     try: 
      class_method(type(self), foo) # raises NameError 
     except NameError: 
      pass 

     self.class_method(foo) # this works 
     Test.class_method(foo) # so does this 

    @classmethod 
    def class_method(cls, foo): 
     print("class_method", cls, foo) 
     # from a class method, you can call a method via the automatically provided cls 
     cls.static_method(foo) 

    @staticmethod 
    def static_method(foo): 
     print("static_method", foo) 
     # a static method can only use the global class name to call other methods 
     if isinstance(foo, int) and foo > 0: 
      Test.static_method(foo - 1) 

    # Class level code is perilous. 
    #normal_method('x', 2) # could work in Python 3 (Python 2 checks the type of self) 
          # but it probably won't be useful (since self is not an instance) 
    #class_method('x', 2) # Won't work. A classmethod descriptor isn't directly callable 
    #staticmethod(2)  # Nor is a staticmethod 

# Top level code (these are all valid) 
Test().normal_method(2) # also could be Test.normal_method(Test(), 2) 
Test.class_method(2) # could also be Test().class_method(2) (type of the instance is used) 
Test.static_method(2) # could also be Test().static_method(2) (instance is ignored) 
相關問題