Método Python vs função [duplicado]

Esta pergunta já tem uma resposta:

Estou à procura de uma confirmação se o meu pensamento está correcto em termos do método Python vs função:

um método faz parte de uma classe.

uma função é definida fora de uma função classe.

por isso, por exemplo

class FooBar(object):
    def __init__(self):
        pass
    def foo(self):
        pass


def bar():
    pass


if __name__ == '__main__':
    fb = FooBar()

eu entendo def foo define o método e def bar define a função. Estou certo?

Author: E. Ducateme, 2017-10-09

2 answers

Sim. Para ser claro, os métodos são funções, são simplesmente ligadas à classe, e quando essa função é chamada de uma instância, ela passa essa instância implicitamente como o primeiro argumento automagicamente. Não importa onde essa função é definida. Considere:
class FooBar:
    def __init__(self, n):
        self.n = n
    def foo(self):
        return '|'.join(self.n*['foo'])


fb = FooBar(2)

print(fb.foo())

def bar(self):
    return '*'.join(self.n*['bar'])

print(bar(fb))

FooBar.bar = bar

print(fb.bar())
 1
Author: juanpa.arrivillaga, 2017-10-08 21:40:56

Na verdade, métodos e funções em Python são exatamente a mesma coisa!

Não importa nem um pouco onde está definido. O que importa é como é estudado.

def defined_outside(*args):
    return args

class C:

    def defined_inside(*args):
        return args

C.defined_outside = defined_outside
defined_inside = C.defined_inside

instance = C()

print(         defined_inside (1,2))
print(         defined_outside(1,2))
print(instance.defined_inside (1,2))
print(instance.defined_outside(1,2))

Que dá a saída

(1, 2)
(1, 2)
(<__main__.C object at 0x7f0c80d417f0>, 1, 2)
(<__main__.C object at 0x7f0c80d417f0>, 1, 2)

(isto só funcionará no Python 3: dois destes irão produzir um TypeError no Python 2.)

O que é importante notar sobre a saída é que, nos dois primeiros casos, as funções recebem dois argumentos: 1 e 2. Nos dois últimos casos, receber três argumentos: instance, 1 e 2

Nos casos em que instance é passado para a função, a função está a comportar-se como um método. Nos casos em que instance é Não passado, a função está a comportar-se como uma função simples. Mas note que ambos os comportamentos são exibidos pela função que foi definida dentro do impasse e pela que foi definida fora da classe.

O que importa é como a função foi pesquisada. Se ele foi visto como um atributo de uma instância de uma classe, então a função se comporta como um método; caso contrário, ela se comporta como uma função livre.

[incidentalmente, este comportamento de ligação {[27] } só funciona para funções Python puras; não funciona para funções definidas usando a API Python/C. Este último comporta-se sempre como funções e nunca como métodos:

C.dir = dir
instance.dir()

Dar-lhe-á um directório do âmbito global, não de instance, indicando que dir recibido zero argumentos, em vez de receber instance como argumento. ]

 1
Author: jacg, 2017-10-08 21:53:44