2010-09-24 3 views
53

Может кто-нибудь, пожалуйста, объясните мне в очень простых терминах, что такое «метод» в Python?Что такое «метод» в Python?

Вещь во многих учебниках Python для начинающих это слово используется таким образом, как если бы новичок уже знал, что такое метод в контексте Python. Хотя я, конечно, знаком с общим значением этого слова, я не знаю, что означает этот термин в Python. Итак, пожалуйста, объясните мне, что такое метод «Питон».

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

+1

"много учебных пособий Python"? О каких конкретных учебниках вы говорите? Мы не можем рекомендовать другую, если мы не знаем, что вы сейчас читаете. –

+4

Метод - это общий термин, он не имеет никакого значения в Python, вероятно, поэтому он используется так беззаботно. См. Http://en.wikipedia.org/wiki/Method_(computer_science) –

+0

@ S.Lott: Извините, пожалуй, я был слишком абсолютистским, передавая свое мнение относительно учебников Python. – brilliant

ответ

66

Это функция, которая является членом класса:

class C: 
    def my_method(self): 
     print "I am a C" 

c = C() 
c.my_method() # Prints "I am a C" 

Простой, как это!

(Есть также некоторые альтернативные виды методов, позволяющие контролировать взаимосвязь между классом и функцией. Но я предполагаю, что вы не спрашиваете об этом, а скорее об основах.)

+7

Здесь стоит отметить, что экземпляр должен быть вручную передан в метод, и по соглашению он передается как «self». – Skilldrick

+7

@Silldrick: Вы, возможно, имеете в виду правильную вещь, но ваш комментарий как есть - подразумевает что-то не так. Экземпляр не должен передаваться явно/вручную при вызове метода на нем. Но метод должен получить его явно, т. Е. Вам нужно вручную добавить параметр для экземпляра (который, да, называется условным). – delnan

+4

@ delnan - Да, спасибо за разъяснение - когда я говорю вручную, передавая то, что я действительно имею в виду, это должно быть явно получено как параметр, но оно передается неявно. – Skilldrick

34

Метод - это функция, которая принимает экземпляр класса как свой первый параметр. Методы являются членами классов.

class C: 
    def method(self, possibly, other, arguments): 
     pass # do something here 

Как вы хотели знать, что конкретно это означает в Python, можно различать связанные и несвязанные методы. В Python все функции (и как таковые также методы) являются объектами, которые можно передавать и «играть с». Таким образом, разница между несвязанными и связанными методами:

1) Связанные методами

# Create an instance of C and call method() 
instance = C() 

print instance.method # prints '<bound method C.method of <__main__.C instance at 0x00FC50F8>>' 
instance.method(1, 2, 3) # normal method call 

f = instance.method 
f(1, 2, 3) # method call without using the variable 'instance' explicitly 

Связанные методами являются методами, которые принадлежат экземплярам класса. В этом примере instance.method связан с экземпляром instance. Каждый раз, когда этот связанный метод вызывается, экземпляр автоматически передается в качестве первого параметра - который называется конвенцией по умолчанию self.

2) несвязанные методы

print C.method # prints '<unbound method C.method>' 
instance = C() 
C.method(instance, 1, 2, 3) # this call is the same as... 
f = C.method 
f(instance, 1, 2, 3) # ..this one... 

instance.method(1, 2, 3) # and the same as calling the bound method as you would usually do 

При доступе C.method (метод внутри класса, а не внутри экземпляра), вы получите несвязанный метод. Если вы хотите его вызвать, вам нужно передать экземпляр как первый параметр, потому что метод не связан с любым экземпляром.

Зная эту разницу, вы можете использовать функции/методы как объекты, например, методы передачи. В качестве примера используйте случай, представьте API, который позволяет определить функцию обратного вызова, но вы хотите предоставить метод в качестве функции обратного вызова. Нет проблем, просто передайте self.myCallbackMethod в качестве обратного вызова, и он будет автоматически вызван с экземпляром в качестве первого аргумента. Это было бы невозможно в статических языках, таких как C++ (или только с обманом).

Надеюсь, у вас есть смысл;) Я думаю, что это все, что вам нужно знать об основах метода. Вы также можете прочитать о декораторах classmethod и staticmethod, но это еще одна тема.

+0

Благодарим вас, AndiDog, за этот расширенный ответ и за ваше время, которое вы потратили на него. Я изучаю это в данный момент. – brilliant

+3

+1 за отличное объяснение связанного и несвязанного. – snapshoe

+0

Супер интересный, спасибо за объяснение. Похоже, это необычно агрессивное соглашение для python (смещение по всем последующим аргументам, когда оно вызывается с точечной нотацией на экземпляре класса), но определенно имеет смысл. –

1

Извините, но - на мой взгляд - RichieHindle совершенно прав, говоря о том, что метод ...

Это функция, которая является членом класса.

Ниже приведен пример функции, которая становится членом класса. С тех пор он ведет себя как метод класса. Давайте начнем с пустой класса и нормальной функции с одним аргументом:

>>> class C: 
...  pass 
... 
>>> def func(self): 
...  print 'func called' 
... 
>>> func('whatever') 
func called 

Теперь мы добавим элемент в C класса, который является ссылкой на функцию. После этого мы можем создать экземпляр класса и вызвать его метод, как если бы он был определен внутри класса:

>>> C.func = func 
>>> o = C() 
>>> o.func() 
func called 

Мы можем использовать также альтернативный способ вызова метода:

>>> C.func(o) 
func called 

o.func даже проявляется точно так же, как метод класса:

>>> o.func 
<bound method C.func of <__main__.C instance at 0x000000000229ACC8>> 

И мы можем попробовать обращенный подход. Давайте определим класс и украдим его метод как функцию:

>>> class A: 
...  def func(self): 
...   print 'aaa' 
... 
>>> a = A() 
>>> a.func 
<bound method A.func of <__main__.A instance at 0x000000000229AD08>> 
>>> a.func() 
aaa 

До сих пор это выглядело так же. Теперь функция угон:

>>> afunc = A.func 
>>> afunc(a) 
aaa  

Истина заключается в том, что метод не принимает «все, что» аргумент:

>>> afunc('whatever') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method func() must be called with A instance as first 
    argument (got str instance instead) 

ИМХО, это не аргумент против метода является функцией, которая является членом класса.

Позже найденоAlex Martelli's answer, что в основном говорит то же самое. К сожалению, если вы считаете его тиражирование :)

+0

В delnan: Вы написали: «Экземпляр не должен передаваться явно/вручную при вызове метода на нем». Собственно, вы должны передать это явно. Единственная синтаксическая разница заключается в том, что вы не пишете ее как первый аргумент в круглых скобках. Помещая его перед именем метода (разделенным точкой) и опуская идентификатор класса, на самом деле является синтаксическим сахаром. – pepr

0

http://docs.python.org/2/tutorial/classes.html#method-objects

Обычно, метод вызывается сразу после того, как он связан:

x.f() 

В примере MyClass, это вернет строку «привет Мир'. Однако нет необходимости сразу обращаться к методу: x.f является объектом метода и может храниться и вызываться позднее. Для Например:

xf = x.f 
while True: 
    print xf() 

будет продолжать печатать привет мир до конца времени.

Что именно происходит при вызове метода? Возможно, вы заметили , что x.f() был вызван без аргумента выше, хотя определение функции для f() задало аргумент. Что случилось с аргументом ?Конечно, Python генерирует исключение, когда функция, которая требует аргумент называется без каких-либо - даже если аргумент на самом деле не используется ...

На самом деле, вы, возможно, догадались, ответ: специальная вещь о методы заключается в том, что объект передается как первый аргумент функции . В нашем примере вызов x.f() в точности эквивалентен MyClass.f (x). В общем случае вызов метода со списком n аргументов эквивалентен вызову соответствующей функции аргументом , который создается путем вставки объекта метода до первого аргумента .

Если вы все еще не понимаете, как работают методы, посмотрите на реализацию , возможно, проясните ситуацию. Когда ссылается атрибут экземпляра , который не является атрибутом данных, его класс выполняется поиск. Если имя обозначает действительный атрибут класса, который является функциональным объектом, объект метода создается путем упаковки (указатели на) объекта экземпляра и объекта функции, только что найденного вместе в абстрактном объекте: это объект метода. Когда объект метода вызывается с помощью списка аргументов , новый список аргументов создается из экземпляра объекта и списка аргументов, а объект функции вызывается с этим новым списком аргументов.

15

В Python метод является функцией, которая доступна для данного объекта из-за типа объекта.

Например, если вы создаете my_list = [1, 2, 3], метод append может быть применен к my_list, потому что это список Python: my_list.append(4). Все списки имеют метод append просто потому, что это списки.

В качестве другого примера, если вы создаете my_string = 'some lowercase text' метод upper может быть применен к my_string просто потому, что это строка Python: my_string.upper().

В списках нет метода upper, а строки не имеют метода append. Зачем? Поскольку методы существуют только для определенного объекта, если они были определены для этого типа объекта, а разработчики Python (до сих пор) решили, что эти конкретные методы не нужны для этих конкретных объектов.

Для вызова метода формат object_name.method_name(), и любые аргументы метода перечислены в круглых скобках. Метод неявно действует на имя объекта, и, следовательно, некоторые методы не имеют никаких утвержденных аргументов, поскольку сам объект является единственным необходимым аргументом. Например, my_string.upper() не имеет перечисленных аргументов, поскольку единственным обязательным аргументом является сам объект, my_string.

Одна общая точка путанице считает следующее:

import math 
math.sqrt(81) 

ли sqrt это метод math объекта? Нет. Как вы называете функцию sqrt от модуля math. Используемый формат: module_name.function_name(), вместо object_name.method_name(). В общем, единственный способ различать эти два формата (визуально) - это посмотреть в остальной части кода и посмотреть, находится ли часть до периода (, my_list, my_string) определяется как объект или модуль.

+2

Разъясняется так хорошо для новичка :) –