your programing

파이썬에서 '자아'라는 단어의 목적은 무엇입니까?

lovepro 2020. 9. 27. 13:35
반응형

파이썬에서 '자아'라는 단어의 목적은 무엇입니까?


self파이썬 에서 단어 의 목적은 무엇입니까 ? 해당 클래스에서 생성 된 특정 개체를 참조한다는 것을 이해하지만 매개 변수로 모든 함수에 명시 적으로 추가해야하는 이유를 알 수 없습니다. 설명하기 위해 Ruby에서 다음과 같이 할 수 있습니다.

class myClass
    def myFunc(name)
        @name = name
    end
end

아주 쉽게 이해합니다. 그러나 Python에서는 self다음 을 포함해야합니다 .

class myClass:
    def myFunc(self, name):
        self.name = name

누구든지 이것을 통해 나에게 말할 수 있습니까? 내 (허용되는 제한적) 경험에서 만난 것이 아닙니다.


사용해야하는 이유 self.는 Python이 @인스턴스 속성을 참조 하는 데 구문을 사용하지 않기 때문 입니다. 파이썬은 메서드가 속한 인스턴스가 자동으로 전달 되지만 자동으로 수신 되지 않도록 하는 방식으로 메서드를 수행하기로 결정했습니다. 메서드 의 첫 번째 매개 변수는 메서드가 호출되는 인스턴스입니다. 이는 메소드를 함수와 완전히 동일하게 만들고 실제 이름을 사용자에게 남겨 둡니다 ( self관습 이지만 다른 것을 사용할 때 사람들은 일반적으로 눈살을 찌푸립니다.) self코드에 특별한 것이 아니라 다른 객체 일뿐입니다. .

파이썬은 일반 이름을 속성과 구별하기 위해 다른 작업을 수행 할 수있었습니다. Ruby와 같은 특수 구문, C ++ 및 Java와 같은 선언이 필요하거나 아마도 더 다른 작업이 필요했습니다.하지만 그렇지 않았습니다. 파이썬은 모든 것을 명시 적으로 만들고, 무엇이 무엇인지 분명하게 만들고, 모든 곳에서 완전히 수행하지는 않지만 인스턴스 속성에 대해 수행합니다. 그렇기 때문에 인스턴스 속성에 할당하려면 할당 할 인스턴스를 알아야하고 self..


간단한 벡터 클래스를 살펴 보겠습니다.

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.


명시 적 요소의 필요성을 이해하는 또 다른 방법은 selfPython이 구문 적 설탕을 추가하는 위치를 확인하는 것입니다. 명심할 때 기본적으로 다음과 같은 전화가

v_instance.length()

내부적으로

Vector.length(v_instance)

어디에 self맞는지 쉽게 알 수 있습니다 . 실제로 Python에서 인스턴스 메서드를 작성하지 않습니다. 작성하는 것은 인스턴스를 첫 번째 매개 변수로 취해야하는 클래스 메소드입니다. 따라서 인스턴스 매개 변수를 어딘가에 명시 적으로 배치해야합니다.


다음 과 같이 정의 된 ClassA메서드를 포함하는 클래스가 있다고 가정 해 보겠습니다 methodA.

def methodA(self, arg1, arg2):
    # do something

그리고 ObjectA이 클래스의 인스턴스입니다.

이제 ObjectA.methodA(arg1, arg2)호출되면 python이 내부적으로 다음과 같이 변환합니다.

ClassA.methodA(ObjectA, arg1, arg2)

self변수 객체 자체를 의미한다.


개체가 인스턴스화되면 개체 자체가 self 매개 변수로 전달됩니다.

여기에 이미지 설명 입력

이 때문에 개체의 데이터가 개체에 바인딩됩니다. 다음은 각 개체의 데이터가 어떻게 보이는지 시각화하는 방법의 예입니다. 'self'가 개체 이름으로 어떻게 바뀌는 지 확인하십시오. 아래의 예제 다이어그램이 완전히 정확하다고 말하는 것은 아니지만 자아의 사용을 시각화하는 데 목적이 있기를 바랍니다.

여기에 이미지 설명 입력

Object는 자체 매개 변수로 전달되어 객체가 자체 데이터를 유지할 수 있습니다.

이것이 완전히 정확하지는 않지만 다음과 같이 개체를 인스턴스화하는 프로세스를 생각해보십시오. 개체가 만들어지면 클래스를 자체 데이터 및 메서드에 대한 템플릿으로 사용합니다. 자체 이름을 self 매개 변수에 전달하지 않으면 클래스의 속성과 메서드가 일반 템플릿으로 유지되고 개체에 대해 참조되지 않습니다. 따라서 객체의 이름을 self 매개 변수에 전달하면 100 개의 객체가 하나의 클래스에서 인스턴스화되면 모두 자신의 데이터와 메서드를 추적 할 수 있습니다.

아래 그림을 참조하십시오.

여기에 이미지 설명 입력


이 예를 좋아합니다.

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: []

클래스를 사용하지 않는 코드로 설명하겠습니다 .

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 문서 에서 발췌 한 것입니다 .

Modula-3에서와 같이 메서드에서 객체의 멤버를 참조하기위한 [Python에서] 속기가 없습니다. 메서드 함수는 호출에 의해 암시 적으로 제공되는 객체를 나타내는 명시적인 첫 번째 인수로 선언됩니다.

종종 메서드의 첫 번째 인수를 self라고합니다. 이것은 관습 일뿐입니다. self라는 이름은 파이썬에 절대적으로 특별한 의미가 없습니다. 그러나 규칙을 따르지 않으면 다른 Python 프로그래머가 코드를 읽을 수 없게 될 수 있으며 이러한 규칙에 의존하는 클래스 브라우저 프로그램이 작성 될 수도 있습니다.

자세한 내용 은 클래스에 대한 Python 설명서 자습서를 참조하십시오 .


이미 언급 된 다른 모든 이유와 마찬가지로 재정의 된 메서드에 쉽게 액세스 할 수 있습니다. 전화 할 수 있습니다 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"

그 사용은 this자바에서 키워드를 사용하는 것과 유사합니다. 즉, 현재 객체에 대한 참조를 제공합니다.


Python은 Java 또는 C ++와 달리 객체 지향 프로그래밍을 위해 만들어진 언어가 아닙니다.

파이썬에서 정적 메서드를 호출 할 때, 그 안에 일반 인수가있는 메서드를 작성하기 만하면됩니다.

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 "객체 지향 프로그래밍"을 참조하십시오. 이것을 이해하면 그 질문을 할 필요조차 없습니다. :).


"명시적인 것이 묵시적인 것보다 낫다"라는 파이썬 선을 따르는 것입니다. 실제로 클래스 객체에 대한 참조입니다. 예를 들어 Java 및 PHP에서는 this.

user_type_name모델의 필드 인 경우 self.user_type_name.


self객체 자체에 대한 객체 참조이므로 동일합니다. 파이썬 메서드는 객체 자체의 컨텍스트에서 호출되지 않습니다. self파이썬에서는 커스텀 객체 모델이나 무언가를 다루는 데 사용될 수 있습니다.


우선, 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

코드는 여기


I'm surprised nobody has brought up Lua. Lua also uses the 'self' variable however it can be omitted but still used. C++ does the same with 'this'. I don't see any reason to have to declare 'self' in each function but you should still be able to use it just like you can with lua and C++. For a language that prides itself on being brief it's odd that it requires you to declare the self variable.


The use of the argument, conventionally called self isn't as hard to understand, as is why is it necessary? Or as to why explicitly mention it? That, I suppose, is a bigger question for most users who look up this question, or if it is not, they will certainly have the same question as they move forward learning python. I recommend them to read these couple of blogs:

1: Use of self explained

Note that it is not a keyword.

The first argument of every class method, including init, is always a reference to the current instance of the class. By convention, this argument is always named self. In the init method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called. For example the below code is the same as the above code.

2: Why do we have it this way and why can we not eliminate it as an argument, like Java, and have a keyword instead

Another thing I would like to add is, an optional self argument allows me to declare static methods inside a class, by not writing self.

Code examples:

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:This works only in Python 3.x.

In previous versions, you have to explicitly add @staticmethod decorator, otherwise self argument is obligatory.


Take a look at the following example, which clearly explains the purpose of 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 is used/needed to distinguish between instances.


Is because by the way python is designed the alternatives would hardly work. Python is designed to allow methods or functions to be defined in a context where both implicit this (a-la Java/C++) or explicit @ (a-la ruby) wouldn't work. Let's have an example with the explicit approach with python conventions:

def fubar(x):
    self.x = x

class C:
    frob = fubar

Now the fubar function wouldn't work since it would assume that self is a global variable (and in frob as well). The alternative would be to execute method's with a replaced global scope (where self is the object).

The implicit approach would be

def fubar(x)
    myX = x

class C:
    frob = fubar

This would mean that myX would be interpreted as a local variable in fubar (and in frob as well). The alternative here would be to execute methods with a replaced local scope which is retained between calls, but that would remove the posibility of method local variables.

However the current situation works out well:

 def fubar(self, x)
     self.x = x

 class C:
     frob = fubar

here when called as a method frob will receive the object on which it's called via the self parameter, and fubar can still be called with an object as parameter and work the same (it is the same as C.frob I think).


In the __init__ method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called.

self, as a name, is just a convention, call it as you want ! but when using it, for example to delete the object, you have to use the same name: __del__(var), where var was used in the __init__(var,[...])

You should take a look at cls too, to have the bigger picture. This post could be helpful.


self is inevitable.

There was just a question should self be implicit or explicit. Guido van Rossum resolved this question saying self has to stay.

So where the self live?

If we would just stick to functional programming we would not need self. Once we enter the Python OOP we find self there.

Here is the typical use case class C with the method m1

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에 대한 참조 유지하는 것입니다 인스턴스 메소드를 우리가 가지고과 명시 적으로 해당 참조에 액세스 할 수 있습니다.


세 가지 유형의 클래스 메서드가 있습니다.

  • 정적 메서드 (읽기 : 함수),
  • 클래스 메서드,
  • 인스턴스 메서드 (언급 됨).

클래스 인스턴스 객체에 대한 명시 적 참조입니다.

참고 URL : https://stackoverflow.com/questions/2709821/what-is-the-purpose-of-the-word-self-in-python

반응형