2010-10-19 2 views
3

Мой вопрос: около двух ответов на другой вопрос: Using class/static methods as default parameter values within methods of the same class.статический метод как параметр по умолчанию для метода класса

Я пытаюсь понять, есть ли разница между тем, что делают два ответа, и если да, то какие плюсы и минусы каждого.

Вопрос: как использовать метод класса в качестве параметра по умолчанию для метода в том же классе.

Ответ 1: используйте функцию вместо метода класса

class X: 
    def default_func(x): 
     return True 

    def test(self, func = default_func): 
     return func(self) 

Ответ 2: использовать метод класса, но преобразовать его в функцию

def unstaticmethod(static): 
    return static.__get__(None, object) 

class X: 
    @staticmethod 
    def default_func(x): 
     return True 

    def test(self, func = unstaticmethod(default_func)): 
     return func(self) 

Это был изначально написан на Python 2 , но мое резюме (надеюсь) Python 3.

ответ

2

Ответ действительно зависит от других намерений, которые у вас есть для X.default_func. Если вы намереваетесь вызывать X.default_func вне экземпляра X, то вы хотите, чтобы он был статическим методом (ответ 2).

# in other code... 
some_object = "Bring out your dead" 
X.default_func(some_object) 

Если, с другой стороны, вы не ожидали, что будет когда-либо default_func называться только внутри экземпляра X (и, конечно, использовать в качестве значения по умолчанию для test), я бы переписать ответ 1 (и использовать соглашение self).

class X: 
    def default_func(self): 
     return True 

    def test(self, func = default_func): 
     return func(self) 

Как примечание стороны, я хотел бы указать на то, что вы могли бы написать ответ 2 по-разному, чтобы избежать unstaticmethod:

class X: 
    def default_func(x): 
     return True 

    def test(self, func = default_func): 
     return func(self) 

    default_func = staticmethod(default_func) 

Причина, по которой работает это потому, что класс X не является created (и default_func не становится методом X) до тех пор, пока не обработает весь блок под class X: (включая аргумент по умолчанию для test(func)).

+0

Я буду растерян. Если default_func будет только * вызван * в test(), но test() вызывается извне класса, как я могу сделать вызов извне класса, эквивалентного «X(). Test (func = second_func)», где second_func является функцией-членом X. –

+0

Python 2 не имеет понятия «функция-член». Классы и их экземпляры имеют только методы. Если «second_func» является обычным методом экземпляра, вам нужно получить базовую функцию, используя 'im_func':' X(). Test (func = X.second_func.im_func) '. Я не рекомендую это делать. Если вам нужно динамически выбирать методы, вы, вероятно, лучше передаете имена методов в тестовую функцию, а затем выполняете что-то вроде 'getattr (self, func_name)()' в тесте и пусть Python выполняет привязку экземпляра. –