질문자 :richzilla
Python self
word의 목적은 무엇입니까? 해당 클래스에서 생성된 특정 개체를 참조한다는 것을 이해하지만 모든 함수에 매개변수로 명시적으로 추가해야 하는 이유를 알 수 없습니다. 설명을 위해 Ruby에서 다음을 수행할 수 있습니다.
class myClass def myFunc(name) @name = name end end
내가 이해하는 것은 아주 쉽게. self
를 포함해야 합니다.
class myClass: def myFunc(self, name): self.name = name
아무도 이것을 통해 나에게 말할 수 있습니까? 그것은 내 (확실히 제한된) 경험에서 만난 것이 아닙니다.
self.
를 사용해야 하는 이유. 파이썬은 인스턴스 속성을 참조하기 위해 @
구문을 사용하지 않기 때문입니다. 파이썬은 메서드가 속한 인스턴스가 자동으로 전달 되지만 자동으로 수신 되지 않는 방식으로 메서드를 수행하기로 결정했습니다. 메서드의 첫 번째 매개변수는 메서드가 호출된 인스턴스입니다. 이것은 메소드를 함수와 완전히 동일하게 만들고 실제 이름을 사용할 수 있도록 남겨둡니다( self
가 관례이고 사람들이 일반적으로 다른 것을 사용할 때 눈살을 찌푸릴 것입니다.) self
는 코드에 특별하지 않습니다. 다른 개체.
Python은 일반 이름을 속성과 구별하기 위해 다른 작업을 수행할 수 있었습니다. Ruby와 같은 특수 구문이 있거나 C++ 및 Java와 같은 선언이 필요한 경우 또는 더 다른 작업이 필요할 수 있지만 그렇지 않습니다. Python은 모든 것을 명시적으로 만들고 무엇이 무엇인지 명확하게 하기 위한 것입니다. 모든 곳에서 수행하지는 않지만 인스턴스 속성에 대해서는 수행합니다. 이것이 인스턴스 속성에 할당할 때 할당할 인스턴스를 알아야 하는 이유이며 이것이 self.
.
Thomas Wouters다음과 같이 정의된 methodA
메서드를 포함하는 ClassA
클래스가 있다고 가정해 보겠습니다.
def methodA(self, arg1, arg2): # do something
ObjectA
는 이 클래스의 인스턴스입니다.
이제 ObjectA.methodA(arg1, arg2)
가 호출되면 python은 이를 내부적으로 다음과 같이 변환합니다.
ClassA.methodA(ObjectA, arg1, arg2)
self
변수는 객체 자체를 나타냅니다.
Arjun Sreedharan간단한 벡터 클래스를 살펴보겠습니다.
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)
따라서 전체 구조는 동일하게 유지됩니다. 이것을 어떻게 활용할 수 있습니까? Vector
length
메서드를 작성하지 않았다고 잠시 가정하면 다음과 같이 할 수 있습니다.
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에서 인스턴스 메서드를 작성하지 않습니다. 작성하는 것은 인스턴스를 첫 번째 매개변수로 취해야 하는 클래스 메소드입니다. 따라서 인스턴스 매개변수를 명시적으로 어딘가에 배치해야 합니다.
Debilski객체가 인스턴스화되면 객체 자체가 self 매개변수에 전달됩니다.
이 때문에 개체의 데이터는 개체에 바인딩됩니다. 다음은 각 개체의 데이터가 어떻게 보이는지 시각화하는 방법의 예입니다. 'self'가 개체 이름으로 대체되는 방식에 주목하십시오. 아래의 이 예제 다이어그램이 완전히 정확하다고 말하는 것은 아니지만 희망적으로 자기 사용을 시각화하는 데 도움이 되기를 바랍니다.
Object는 self 매개변수로 전달되어 객체가 자체 데이터를 유지할 수 있도록 합니다.
이것이 완전히 정확하지 않을 수도 있지만 다음과 같이 개체를 인스턴스화하는 프로세스를 생각해 보십시오. 개체가 만들어지면 클래스를 자체 데이터 및 메서드에 대한 템플릿으로 사용합니다. 자체 이름을 self 매개변수에 전달하지 않으면 클래스의 속성과 메서드는 일반 템플릿으로 유지되고 개체에 대해 참조(소속)되지 않습니다. 따라서 객체의 이름을 self 매개변수에 전달하면 한 클래스에서 100개의 객체가 인스턴스화되면 모두 자신의 데이터와 메서드를 추적할 수 있음을 의미합니다.
아래 그림을 참조하십시오.
sw123456나는 이 예를 좋아한다:
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: []
kame클래스를 사용하지 않는 코드로 시연하겠습니다.
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'
클래스는 항상 이 "상태"를 전달하는 것을 피하는 방법일 뿐입니다(초기화, 클래스 구성, 거의 필요하지 않은 메타클래스 및 연산자를 재정의하는 사용자 지정 메서드 지원과 같은 기타 좋은 기능).
이제 내장된 파이썬 클래스 기계를 사용하여 위의 코드를 시연하여 기본적으로 어떻게 동일한지 보여 보겠습니다.
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 )
[중복된 닫힌 질문에서 내 답변을 마이그레이션했습니다.]
ninjagecko다음은 self 에 대한 Python 문서 에서 발췌한 것입니다.
Modula-3에서와 같이 [파이썬에는] 메서드에서 객체의 멤버를 참조하는 속기가 없습니다. 메서드 함수는 호출에 의해 암시적으로 제공되는 객체를 나타내는 명시적 첫 번째 인수로 선언됩니다.
종종 메서드의 첫 번째 인수를 self라고 합니다. 이것은 관례에 불과합니다. self라는 이름은 Python에 특별한 의미가 전혀 없습니다. 그러나 규칙을 따르지 않으면 다른 Python 프로그래머가 코드를 덜 읽을 수 있으며 이러한 규칙에 의존하는 클래스 브라우저 프로그램이 작성될 수도 있습니다.
자세한 내용 은 클래스에 대한 Python 설명서 자습서를 참조하십시오.
Matthew Rankin이미 언급된 다른 모든 이유와 마찬가지로 재정의된 메서드에 더 쉽게 액세스할 수 있습니다. Class.some_method(inst)
호출할 수 있습니다.
유용한 예:
class C1(object): def __init__(self): print "C1 init" class C2(C1): def __init__(self): #overrides C1.__init__ print "C2 init" C1.__init__(self) #but we still want C1 to init the class too
>>> C2() "C2 init" "C1 init"
Ponkadoodlethis
키워드의 사용은 Java에서 this 키워드를 사용하는 것과 유사합니다. 즉, 현재 개체에 대한 참조를 제공합니다.
Gaurav NishantPython은 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 변수를 참조하고 있습니다. 기억하십시오: 메소드 내에 변수가 있으면 self가 작동하지 않습니다. 해당 변수는 해당 메서드가 실행되는 동안에만 존재합니다. 필드(전체 클래스의 변수)를 정의하려면 클래스 메서드 외부에서 필드를 정의해야 합니다.
내 말을 한 마디도 이해하지 못한다면 Google "객체 지향 프로그래밍"을 참조하십시오. 이것을 이해하면 그런 질문을 할 필요조차 없습니다. :).
ytpillaiself
는 객체 자체에 대한 객체 참조이므로 동일합니다. Python 메서드는 개체 자체의 컨텍스트에서 호출되지 않습니다. self
는 사용자 정의 객체 모델 또는 무언가를 처리하는 데 사용될 수 있습니다.
Ming-TangPython zen "명시적인 것이 암시적인 것보다 낫다"를 따르기 위해 거기에 있습니다. 실제로 클래스 개체에 대한 참조입니다. 예를 들어 Java와 PHP에서는 이것을 this
라고 합니다.
user_type_name
이 모델의 필드인 경우 self.user_type_name
액세스합니다.
dan-klasson우선, 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
코드는 여기
Akash Kandpal아무도 Lua를 키우지 않았다는 사실에 놀랐습니다. Lua는 'self' 변수도 사용하지만 생략할 수 있지만 여전히 사용됩니다. C++는 '이것'과 동일한 작업을 수행합니다. 각 함수에서 'self'를 선언해야 할 이유는 없지만 lua 및 C++에서와 마찬가지로 여전히 사용할 수 있어야 합니다. 간결함을 자랑스럽게 여기는 언어의 경우 자체 변수를 선언해야 한다는 것은 이상한 일입니다.
user441521self
라고 불리는 논증의 사용은 이해하기 어렵지 않습니다. 왜 필요한가요? 또는 명시적으로 언급하는 이유는 무엇입니까? 이것은 이 질문을 찾는 대부분의 사용자에게 더 큰 질문이라고 생각합니다. 그렇지 않은 경우 Python 학습을 진행하면서 확실히 동일한 질문을 하게 될 것입니다. 나는 그들에게 다음 두 개의 블로그를 읽을 것을 권장합니다.
1: 자체 설명 사용
키워드가 아니니 참고하세요.
init를 포함한 모든 클래스 메소드의 첫 번째 인수는 항상 클래스의 현재 인스턴스에 대한 참조입니다. 관례에 따라 이 인수의 이름은 항상 self입니다. init 메소드에서 self는 새로 생성된 객체를 참조합니다. 다른 클래스 메서드에서는 메서드가 호출된 인스턴스를 참조합니다. 예를 들어 아래 코드는 위 코드와 동일합니다.
2: 왜 우리는 그것을 이런 식으로 가지고 있고 왜 우리는 그것을 Java와 같은 인수로 제거하지 못하고 대신 키워드를 가질 수 있습니까?
추가하고 싶은 또 다른 사항은 선택적 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"
추신 : 이것은 Python 3.x에서만 작동합니다.
@staticmethod
데코레이터를 명시적으로 추가해야 했으며, 그렇지 않으면 self
인수가 필수입니다.
Bugs Buggyself
의 목적을 명확하게 설명하는 다음 예를 살펴보십시오.
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
는 인스턴스를 구별하는 데 사용/필요합니다.
출처: 파이썬의 자체 변수 설명 - Pythontips
kmario23python이 설계된 방식으로 대안이 거의 작동하지 않기 때문입니다. 파이썬은 방법이나 기능이 맥락에서 정의 할 수 있도록 설계되는 경우 모두 암시 this
(- 라 자바 / C ++) 또는 명시 적 @
작동하지 않을 것입니다 (- 라 루비). 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
나는 생각한다).
skyking__init__
메서드에서 self는 새로 생성된 객체를 참조합니다. 다른 클래스 메서드에서는 메서드가 호출된 인스턴스를 참조합니다.
self는 이름으로 단지 관례 일 뿐입니다. 원하는 대로 부르십시오! 그러나 예를 들어 객체를 삭제하기 위해 사용할 때 동일한 이름을 사용해야 합니다: __del__(var)
, 여기서 var
는 __init__(var,[...])
더 큰 그림 을 cls
도 살펴봐야 합니다. 이 게시물 이 도움이 될 수 있습니다.
Oussama L.self 는 현재 객체 이름이나 class 의 인스턴스처럼 작동합니다.
# Self explanation. class classname(object): def __init__(self,name): self.name=name # Self is acting as a replacement of object name. #self.name=object1.name def display(self): print("Name of the person is :",self.name) print("object name:",object1.name) object1=classname("Bucky") object2=classname("ford") object1.display() object2.display() ###### Output Name of the person is : Bucky object name: Bucky Name of the person is : ford object name: Bucky
sameer_nubiaself
는 불가피하다.
단지 있었다 질문 해야 self
암시 적 또는 명시가. Guido van Rossum
self
가 머물러야 한다며 이 질문을 해결했습니다.
그렇다면 self
어디에 사는가?
우리가 함수형 프로그래밍을 고수한다면 self
는 필요하지 않을 것입니다. 일단 파이썬 OOP에 들어가면 우리는 그곳에서 self
을 찾습니다.
m1
메서드를 사용하는 일반적인 사용 사례 class C
class C: def m1(self, arg): print(self, ' inside') pass ci =C() print(ci, ' outside') ci.m1(None) print(hex(id(ci))) # hex memory address
이 프로그램은 다음을 출력합니다.
<__main__.C object at 0x000002B9D79C6CC0> outside <__main__.C object at 0x000002B9D79C6CC0> inside 0x2b9d79c6cc0
따라서 self
는 클래스 인스턴스의 메모리 주소를 보유합니다. self
의 목적 은 인스턴스 메서드에 대한 참조를 보유하고 해당 참조에 대한 명시적 액세스 권한을 갖는 것입니다.
클래스 메서드에는 세 가지 유형이 있습니다.
- 정적 메서드(읽기: 함수),
- 클래스 메소드,
- 인스턴스 메서드(언급됨).
prosti클래스 인스턴스 객체에 대한 명시적 참조입니다.
SilentGhost문서에서 ,
메소드의 특별한 점은 인스턴스 객체가 함수의 첫 번째 인수로 전달된다는 것입니다. 이 예에서 xf()
MyClass.f(x)
와 정확히 동일합니다. 일반적으로 n개의 인수 목록으로 메서드를 호출하는 것은 첫 번째 인수 앞에 메서드의 인스턴스 개체를 삽입하여 만든 인수 목록으로 해당 함수를 호출하는 것과 같습니다.
이 관련 스니펫 앞에
class MyClass: """A simple example class""" i = 12345 def f(self): return 'hello world'
x = MyClass()
nmxl적어도 Python의 경우 self 매개변수는 자리 표시자로 생각할 수 있습니다. 이것을 보십시오:
class Person: def __init__(self, name, age): self.name = name self.age = age p1 = Person("John", 36) print(p1.name) print(p1.age)
이 경우 self 와 다른 많은 사람들이 이름 값을 저장하는 방법으로 사용되었습니다. 그러나 그 후에는 p1을 사용하여 사용 중인 클래스에 할당합니다. 그런 다음 인쇄할 때 동일한 p1 키워드를 사용합니다.
이것이 파이썬에 도움이 되기를 바랍니다!
Rishi"self" 키워드는 클래스의 참조를 보유하며 사용 여부는 사용자에게 달려 있지만 파이썬에서 새 메서드를 생성할 때마다 파이썬은 자동으로 self 키워드를 작성합니다. R&D를 하다 보면 클래스에 두 개의 메소드를 생성하고 내부에서 하나를 호출하려고 하면 self(클래스 참조)를 추가하지 않는 한 메소드를 인식하지 못한다는 것을 알 수 있습니다.
class testA: def __init__(self): print('ads') def m1(self): print('method 1') self.m2() def m2(self): print('method 2')
아래 코드는 해결할 수 없는 참조 오류를 발생시킵니다.
class testA: def __init__(self): print('ads') def m1(self): print('method 1') m2() #throws unresolvable reference error as class does not know if m2 exist in class scope def m2(self): print('method 2')
이제 아래 예제를 보자
class testA: def __init__(self): print('ads') def m1(self): print('method 1') def m2(): print('method 2')
이제 testA 클래스의 객체를 생성할 때 m1() 메서드에 self 키워드가 포함되어 있으므로 이와 같은 클래스 객체를 사용하여 m1() 메서드를 호출할 수 있습니다.
obj = testA() obj.m1()
하지만 m2() 메서드를 호출하려는 경우 자체 참조가 없으므로 아래와 같이 클래스 이름을 사용하여 m2()를 직접 호출할 수 있습니다.
testA.m2()
그러나 내부에 전역 변수를 만드는 것과 같은 다른 이점도 있으므로 self 키워드로 생활하는 것을 연습하십시오.
Rahul Jha내 작은 2 센트
이 Person 클래스에서 우리 는 self와 함께 init 메소드를 정의했으며 여기서 주목해야 할 흥미로운 점은 self 와 인스턴스 변수 p 의 메모리 위치가 동일 <__main__.Person object at 0x106a78fd0>
class Person: def __init__(self, name, age): self.name = name self.age = age def say_hi(self): print("the self is at:", self) print((f"hey there, my name is {self.name} and I am {self.age} years old")) def say_bye(self): print("the self is at:", self) print(f"good to see you {self.name}") p = Person("john", 78) print("the p is at",p) p.say_hi() p.say_bye()
따라서 위에서 설명한 것처럼 self와 instance 변수는 동일한 객체입니다.
saran'self'라는 단어는 클래스의 인스턴스를 나타냅니다.
class foo: def __init__(self, num1, num2): self.n1 = num1 #now in this it will make the perimeter num1 and num2 access across the whole class self.n2 = num2 def add(self): return self.n1 + self.n2 # if we had not written self then if would throw an error that n1 and n2 is not defined and we have to include self in the function's perimeter to access it's variables
PYC출처 : http:www.stackoverflow.com/questions/2709821/what-is-the-purpose-of-the-word-self