Метод может быть вызван следующим образом. Есть также больше возможностей (проверьте отражение api), но это самый простой:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Assert;
import org.junit.Test;
public class ReflectionTest {
private String methodName = "length";
private String valueObject = "Some object";
@Test
public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Method m = valueObject.getClass().getMethod(methodName, new Class[] {});
Object ret = m.invoke(valueObject, new Object[] {});
Assert.assertEquals(11, ret);
}
}
Причина, по которой вам нужно использовать self.
, заключается в том, что Python не использует синтаксис @
для ссылки на атрибуты экземпляра. Python решил делать методы таким образом, чтобы автоматически использовать экземпляр, к которому принадлежит этот метод, , переданный , но не получен : первым параметром методов является экземпляр метода вызывается. Это делает методы полностью такими же, как и функции, и оставляет фактическое имя для использования до вас (хотя self
является конвенцией, и люди обычно будут хмуриться вам, когда вы используете что-то другое.) self
не является особым для код, это просто еще один объект.
Python мог бы сделать что-то еще, чтобы отличить нормальные имена от атрибутов - специальный синтаксис, например Ruby, или требовать объявления, подобные C ++ и Java, или, возможно, что-то еще более отличающееся - - но это не так. Python все для того, чтобы сделать вещи явными, делая это очевидным, что к чему, и хотя он не делает это целиком повсюду, он делает это, например, атрибуты. Вот почему назначение атрибуту экземпляра должно знать, какой экземпляр присваивается, и поэтому ему нужно self.
.
Использование аргумента, обычно называемое self
, не так сложно понять, как это необходимо? Или о том, почему прямо упоминать об этом? Это, я полагаю, является большим вопросом для большинства пользователей, которые ищут этот вопрос, или если это не так, у них, безусловно, будет тот же вопрос, что и в дальнейшем, изучая python. Я рекомендую им прочитать эти две блоги:
Обратите внимание, что это не ключевое слово.
< blockquote>Первый аргумент каждого метода класса, включая init, всегда является ссылкой на текущий экземпляр класса. По соглашению, этот аргумент всегда называется self. В методе init сам относится к вновь созданному объекту; в других методах класса, это относится к экземпляру, метод которого был вызван. Например, приведенный ниже код такой же, как приведенный выше код.
. Еще одна вещь, которую я хотел бы добавить, - необязательный аргумент self
позволяет мне объявлять статические методы внутри класса, не записывая self
.
Примеры кода:
class MyClass():
def staticMethod():
print "This is a static method"
def objectMethod(self):
print "This is an object method which needs an instance of a class, and that is what self refers to"
PS: Это работает только в Python 3.x.
В предыдущих версиях вы должны явно добавить декоратор @staticmethod
в противном случае аргумент self
является обязательным.
Его использование похоже на использование ключевого слова this
в Java, то есть для ссылки на текущий объект.
В методе __init__
self относится к вновь созданному объекту; в других классах он ссылается на экземпляр, метод которого был вызван.
self, как имя, является только соглашением , назовите его так, как вы хотите! но при использовании, например, для удаления объекта, вы должны использовать одно и то же имя: __del__(var)
, где var
использовался в __init__(var,[...])
. Вы должны взглянуть на cls
, чтобы иметь большую картинку . Это сообщение может быть полезно.
Прежде всего, self - это условное имя, вы можете поставить вместо него что-то другое (быть последовательным).
Он относится к самому объекту, поэтому, когда вы его используете, вы объявляете что .name и .age являются свойствами объектов Student (обратите внимание, а не на класс Student), которые вы собираетесь создать.
class Student:
#called each time you create a new Student instance
def __init__(self,name,age): #special method to initialize
self.name=name
self.age=age
def __str__(self): #special method called for example when you use print
return "Student %s is %s years old" %(self.name,self.age)
def call(self, msg): #silly example for custom method
return ("Hey, %s! "+msg) %self.name
#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)
#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self
#you can modify attributes, like when alice ages
alice.age=20
print alice
Допустим, у вас есть класс ClassA
, который содержит метод methodA
, определенный как:
def methodA(self, arg1, arg2):
# do something
и ObjectA
является экземпляром этого класса.
Теперь, когда вызывается ObjectA.methodA(arg1, arg2)
, python внутренне преобразует его для вас как:
ClassA.methodA(ObjectA, arg1, arg2)
Переменная self
относится к самому объекту.
Мне нравится этот пример:
class A:
foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: [5]
class A:
def __init__(self):
self.foo = []
a, b = A(), A()
a.foo.append(5)
b.foo
ans: []
self
, но и от типа переменной. Попробуйте сделать первый пример с простым целым числом вместо списка. Результат будет совсем другим.
– Konstantin
27 March 2014 в 21:18
a.foo
в первом примере, а не A.foo
? Ясно, что foo
принадлежит классу ...
– Radon Rosborough
6 August 2014 в 19:29
a
и b
являются метками (или указателями) для A()
(класс). a.foo
ссылается на метод класса A().foo
. Во втором примере, однако, a
становится ссылкой на экземпляр i> из A()
, как и b
. Теперь, когда они являются экземплярами вместо самого объекта класса, self i> позволяет использовать метод foo
для экземпляров.
– LegendaryDude
12 July 2017 в 17:07
Возьмем простой векторный класс:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
Мы хотим иметь метод, который вычисляет длину. Как бы это выглядело, если бы мы хотели определить его внутри класса?
def length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
Как это должно выглядеть, когда мы должны определять его как глобальный метод / функцию?
def length_global(vector):
return math.sqrt(vector.x ** 2 + vector.y ** 2)
Таким образом, вся структура остается прежней. Как я могу это использовать? Если на какой-то момент мы предположим, что мы не записали метод length
для нашего класса Vector
, мы могли бы это сделать:
Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0
Это работает, потому что первый параметр length_global
, может быть повторно использован как параметр self
в length_new
. Это было бы невозможно без явного self
.
Другой способ понять необходимость явного self
- увидеть, где Python добавляет некоторый синтаксический сахар. Когда вы помните, что в основном вызов, подобный
v_instance.length()
, внутренне преобразован в
Vector.length(v_instance)
, легко увидеть, где находится self
. на самом деле не пишите методы экземпляра в Python; то, что вы пишете, это методы класса, которые должны принимать экземпляр в качестве первого параметра. И поэтому вам нужно будет явно указать параметр экземпляра.
Vector.length_new = length_global
.
– RussW
6 September 2013 в 10:46
Взгляните на следующий пример, в котором четко объясняется, что цель self
class Restaurant(object):
bankrupt = False
def open_branch(self):
if not self.bankrupt:
print("branch opened")
#create instance1
>>> x = Restaurant()
>>> x.bankrupt
False
#create instance2
>>> y = Restaurant()
>>> y.bankrupt = True
>>> y.bankrupt
True
>>> x.bankrupt
False
self
используется / необходима для различения экземпляров.
Следующие фрагменты из документации Python о self :
Как и в Modula-3, для ссылки на элементы объекта нет сокращений [в Python] из его методов: функция метода объявляется с явным первым аргументом, представляющим объект, который предоставляется неявно вызовом.
Часто первый аргумент метода называется self. Это не что иное, как соглашение: имя «я» совершенно не имеет особого значения для Python. Обратите внимание, однако, что, не соблюдая соглашение, ваш код может быть менее читаемым для других программистов на Python, и также возможно, что программа браузера классов может быть написана, которая опирается на такое соглашение.
Для получения дополнительной информации см. учебник по документации Python по классам .
self
является объектной ссылкой на сам объект, поэтому они одинаковы. Методы Python не вызывается в контексте самого объекта. self
в Python может использоваться для обработки пользовательских объектных моделей или чего-то еще.
Я продемонстрирую код, который не использует классы:
def state_init(state):
state['field'] = 'init'
def state_add(state, x):
state['field'] += x
def state_mult(state, x):
state['field'] *= x
def state_getField(state):
return state['field']
myself = {}
state_init(myself)
state_add(myself, 'added')
state_mult(myself, 2)
print( state_getField(myself) )
#--> 'initaddedinitadded'
Классы - это всего лишь способ избежать передачи этой вещи «состояния» все время (и другие приятные вещи, такие как инициализация, класс композиция, редко требуемые метаклассы и поддержка пользовательских методов для переопределения операторов).
Теперь давайте продемонстрируем приведенный выше код, используя встроенный механизм класса python, чтобы показать, как это в основном одно и то же.
class State(object):
def __init__(self):
self.field = 'init'
def add(self, x):
self.field += x
def mult(self, x):
self.field *= x
s = State()
s.add('added') # self is implicitly passed in
s.mult(2) # self is implicitly passed in
print( s.field )
[мигрировал мой ответ из дублированного закрытого вопроса]
'self' используется для ссылки на вновь созданный объект.
, например, если вы объявляете метод в классе по умолчанию, он автоматически принимает экземпляр как первый аргумент.
По соглашению мы называем это «я» в файле python.it просто сильное соглашение. Вы можете назвать это другим именем.
blockquote>Если вы хотите использовать метод, который не нуждается в доступе к себе, используйте staticmethod:
class TestClass(): @staticmethod def staticMethod(other_arg): print "This is a static method" def instanceMethod(self,other_arg): #This is instance method print "self is instance" ##If you want access to the class, but not to the instance, use classmethod: @classmethod def my_class_method(cls, other_arg): print "this is a class method"
Он должен следовать за Python zen «явный лучше, чем неявный». Это действительно ссылка на ваш объект класса. Например, в Java и PHP он называется this
.
Если user_type_name
является полем вашей модели, вы получаете доступ к нему через self.user_type_name
.
это явная ссылка на объект экземпляра класса.
Это потому, что, кстати, дизайн python вряд ли сработает. Python предназначен для определения методов или функций в контексте, где неявные this
(a-la Java / C ++) или явные @
(a-la ruby) не будут работать. Давайте рассмотрим пример с явным подходом с соглашениями python:
def fubar(x):
self.x = x
class C:
frob = fubar
Теперь функция fubar
не будет работать, так как предположим, что self
является глобальной переменной (и в frob
также). Альтернативой было бы выполнить метод с замененной глобальной областью (где self
- это объект).
Неявный подход будет
def fubar(x)
myX = x
class C:
frob = fubar
. Это будет означать, что myX
будет интерпретироваться как локальная переменная в fubar
(а также в frob
). Альтернативой здесь будет выполнение методов с замененной локальной областью, которая сохраняется между вызовами, но это устранит возможность локальных переменных метода.
Однако текущая ситуация работает хорошо:
def fubar(self, x)
self.x = x
class C:
frob = fubar
здесь, когда вызывается как метод frob
, получит объект, по которому он вызывается через параметр self
, и fubar
все еще можно вызвать с объектом в качестве параметра и работать одинаково (это [] совпадает с C.frob
, я думаю).
Когда объекты создаются, сам объект передается в параметр self.
[/g0]
Из-за этого данные объекта привязаны к объекту. Ниже приведен пример того, как вам может показаться, как выглядят данные каждого объекта. Обратите внимание, что «я» заменяется именем объекта. Я не говорю, что приведенная ниже диаграмма ниже полностью точна, но, надеюсь, она служит цели визуализации использования себя.
[/g1]
Объект передается в параметр self, чтобы объект мог сохранять свои собственные данные.
Хотя это может быть не совсем точным, подумайте о процессе создания объекта таким образом: Когда объект создан, он использует класс как шаблон для своих собственных данных и методов. Не передавая свое собственное имя в параметр self, атрибуты и методы в классе оставались бы в качестве общего шаблона и на него не ссылались бы (принадлежат) объекту. Поэтому, передавая имя объекта в параметр self, это означает, что если 100 объектов создаются из одного класса, они могут отслеживать свои собственные данные и методы.
См. Иллюстрацию ниже:
[/g2]
Я удивлен, что никто не воспитывал Луа. Lua также использует переменную «self», однако ее можно опустить, но использовать. C ++ делает то же самое с «этим». Я не вижу причин, чтобы объявлять «я» в каждой функции, но вы все равно сможете использовать ее так же, как вы можете с помощью lua и C ++. Для языка, который гордится тем, что он краток, странно, что он требует, чтобы вы объявили переменную self.
Python не является языком, созданным для объектно-ориентированного программирования, в отличие от Java или C ++.
При вызове статического метода в Python просто записывается метод с регулярными аргументами внутри него.
class Animal():
def staticMethod():
print "This is a static method"
Однако объектный метод, требующий от вас сделать переменную, которая является Animal, в этом случае нуждается в аргументе self
class Animal():
def objectMethod(self):
print "This is an object method which needs an instance of a class"
. Метод self также используется для обозначения поля переменной внутри класса.
class Animal():
#animalName made in constructor
def Animal(self):
self.animalName = "";
def getAnimalName(self):
return self.animalName
В этом случае self относится к переменной animalName для всего класса. ПОМНИТЕ: Если у вас есть переменная внутри метода, я не буду работать. Эта переменная просто существует только тогда, когда этот метод запущен. Для определения полей (переменные всего класса) вы должны определить их OUTSIDE методами класса.
Если вы не понимаете ни слова о том, что я говорю, тогда Google «Объектно-ориентированное программирование». Как только вы это поймете, вам даже не придется задавать этот вопрос:).
staticMethod()
и objectMethod(self)
. Я хотел бы добавить, что для вызова первого вы сказали бы Animal.staticMethod()
, в то время как objectMethod()
нуждается в экземпляре: a = Animal(); a.objectMethod()
– Laryx Decidua
24 July 2015 в 09:37
def getAnimalName
, чтобы не сжимать строку, которую вы пытаетесь вернуть, а self
ссылается на экземпляр класса, а не на любое поле внутри него.
– Cees Timmerman
21 September 2017 в 18:38
cls
относится к объекту класса, а не к экземпляру объекта – SilentGhost 25 April 2010 в 21:33cls
, аself
обычно используется, например, методами. Если бы я хотел, я мог бы использоватьself
для методов класса иcls
для методов экземпляра. Я мог бы также использоватьbob
иfnord
, если бы мне понравилось. – SingleNegationElimination 22 November 2010 в 23:13this
вместоself
. Есть ли уself
некоторая история, о которой я не знаю на более старых языках программирования? – Julius 12 December 2012 в 22:46self
пришел из соглашений Modula-3, см. этот ответ для получения дополнительной информации об этом выборе. (Отказ от ответственности: его шахта). – Bakuriu 20 September 2013 в 20:07