[python] 파이썬에서 명시적인 ‘자기’를 피하는 방법은 무엇입니까?

나는 파이 게임 튜토리얼 을 따라 파이썬을 배우고있다 .

거기에서 키워드 self 의 광범위한 사용을 발견 했으며 주로 Java 배경에서 왔으므로 self 입력하는 것을 잊어 버렸습니다 . 예를 들어, rect 는 이미 클래스의 멤버 변수 이기 때문에을self.rect.centerx 입력 합니다.rect.centerx

자바 병렬 나는이 상황에 멤버 변수에 대한 모든 참조를 접두사 데에 대해 생각할 수있는 .

모든 멤버 변수 앞에 self 접두사를 붙였습니까 ? 그렇지 않도록 선언 할 수있는 방법이 있습니까?

내가 제안하는 것이 pythonic 이 아니더라도 가능하다면 여전히 알고 싶습니다.

나는 이와 관련된 SO 질문을 살펴 보았지만, 내가 겪고있는 것에 대해 대답하지 못했습니다.



답변

파이썬은 self를 명시해야합니다. 결과적으로 전체 클래스 정의가 보이지 않아도 멤버와 그렇지 않은 것에 대해 혼동되지 않습니다. 이로 인해 다음과 같은 유용한 속성이 나타납니다.

하나의 극단적 인 예 : 어떤 기본 클래스에 대한 지식없이 클래스를 작성할 수 있으며 항상 멤버에 액세스하는지 여부를 알고 있습니다.

class A(some_function()):
  def f(self):
    self.member = 42
    self.method()

그것은 완전한 코드입니다! (some_function은 기본으로 사용되는 유형을 반환합니다.)

다른 클래스의 메소드는 동적으로 구성됩니다.

class B(object):
  pass

print B()
# <__main__.B object at 0xb7e4082c>

def B_init(self):
  self.answer = 42
def B_str(self):
  return "<The answer is %s.>" % self.answer
# notice these functions require no knowledge of the actual class
# how hard are they to read and realize that "members" are used?

B.__init__ = B_init
B.__str__ = B_str

print B()
# <The answer is 42.>

이 두 가지 예는 모두 극단적이며 매일 볼 수는 없으며 이와 같은 코드를 자주 작성해야한다고 제안하지는 않지만 명시 적으로 요구되는 자기 측면을 명확하게 보여줍니다.


답변

이전 답변은 모두 기본적으로 “사용할 수 없음”또는 “사용할 수 없음”의 변형입니다. 나는 후자의 감정에 동의하지만, 기술적으로 여전히 대답하지 않습니다.

게다가, 누군가가 실제 질문이하는 것에 따라 누군가 무언가를하고 싶어 할만한 합당한 이유가 있습니다. 내가 때때로 겪는 한 가지는 긴 이름을 사용하면 방정식을 인식 할 수없는 긴 수학 방정식입니다. 미리 준비된 예에서이를 수행 할 수있는 몇 가지 방법은 다음과 같습니다.

import numpy as np
class MyFunkyGaussian() :
    def __init__(self, A, x0, w, s, y0) :
        self.A = float(A)
        self.x0 = x0
        self.w = w
        self.y0 = y0
        self.s = s

    # The correct way, but subjectively less readable to some (like me) 
    def calc1(self, x) :
        return (self.A/(self.w*np.sqrt(np.pi))/(1+self.s*self.w**2/2)
                * np.exp( -(x-self.x0)**2/self.w**2)
                * (1+self.s*(x-self.x0)**2) + self.y0 )

    # The correct way if you really don't want to use 'self' in the calculations
    def calc2(self, x) :
        # Explicity copy variables
        A, x0, w, y0, s = self.A, self.x0, self.w, self.y0, self.s
        sqrt, exp, pi = np.sqrt, np.exp, np.pi
        return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
                * exp( -(x-x0)**2/w**2 )
                * (1+s*(x-x0)**2) + y0 )

    # Probably a bad idea...
    def calc3(self, x) :
        # Automatically copy every class vairable
        for k in self.__dict__ : exec(k+'= self.'+k)
        sqrt, exp, pi = np.sqrt, np.exp, np.pi
        return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
                * exp( -(x-x0)**2/w**2 )
                * (1+s*(x-x0)**2) + y0 )

g = MyFunkyGaussian(2.0, 1.5, 3.0, 5.0, 0.0)
print(g.calc1(0.5))
print(g.calc2(0.5))
print(g.calc3(0.5))

세 번째 예, 즉 사용 for k in self.__dict__ : exec(k+'= self.'+k)은 기본적으로 질문이 실제로 요구하는 것이지만 일반적으로 좋은 생각이라고 생각하지 않는다는 것을 분명히하겠습니다.

클래스 변수 또는 함수를 반복하는 자세한 정보 및 방법은 이 질문에 대한 답변 및 토론을 참조하십시오 . 변수의 이름을 동적으로 지정하는 다른 방법과 이것이 일반적으로 좋지 않은 이유에 대한 설명은 이 블로그 게시물을 참조하십시오 .

업데이트 : Python3의 함수에서 로컬을 동적으로 업데이트하거나 변경할 수있는 방법 이 없으므로 calc3 및 유사한 변형이 더 이상 가능하지 않습니다. 내가 생각할 수있는 유일한 python3 호환 솔루션은 다음을 사용하는 것입니다 globals.

def calc4(self, x) :
        # Automatically copy every class variable in globals
        globals().update(self.__dict__)
        sqrt, exp, pi = np.sqrt, np.exp, np.pi
        return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
                * exp( -(x-x0)**2/w**2 )
                * (1+s*(x-x0)**2) + y0 )

다시 말하지만, 일반적으로 끔찍한 관행입니다.


답변

실제로 self는 키워드가 아니며, 파이썬에서 인스턴스 메소드의 첫 번째 매개 변수에 일반적으로 부여 된 이름 일뿐입니다. 그리고 첫 번째 매개 변수는 메소드가 호출중인 클래스의 인스턴스를 아는 유일한 메커니즘이므로 건너 뛸 수 없습니다.


답변

예를 들어 원하는 이름을 사용할 수 있습니다

class test(object):
    def function(this, variable):
        this.variable = variable

또는

class test(object):
    def function(s, variable):
        s.variable = variable

그러나 당신은 범위의 이름을 사용하여 붙어 있습니다.

나는 당신이 설득력있는 이유가 없다면 경험이 풍부한 pythonistas에게 외계인이 될 수 있기 때문에 자기 자신과 다른 것을 사용하지 않는 것이 좋습니다.


답변

selfpython 철학에 따르면 명시 적이 암시 적보다 낫기 때문에 항상을 지정해야합니다 .

파이썬으로 프로그래밍하는 방식이 자바로 프로그래밍하는 방식과 매우 다르다는 self것을 알 수 있습니다. 따라서 객체 내부의 모든 것을 투영하지 않기 때문에 사용 이 감소하는 경향이 있습니다. 오히려 더 나은 테스트를 위해 모듈 수준 기능을 더 많이 사용합니다.

그건 그렇고. 나는 처음에 그것을 싫어, 지금은 반대 싫어. 들여 쓰기 방식의 흐름 제어에 대해서도 동일합니다.


답변

“self”는 클래스의 현재 객체 인스턴스의 일반적인 자리 표시 자입니다. 마치 “자체”를 참조하는 것처럼 클래스 내부의 객체 속성 또는 필드 또는 메서드를 참조하려고 할 때 사용됩니다. 그러나 파이썬 프로그래밍 영역의 누군가가 “self”를 사용하기 시작하자마자 다른 영역은 “this”를 사용하지만 대체 할 수없는 키워드로 만듭니다. 코드 가독성을 높이기 위해 “its”를 사용했습니다. 파이썬에서 좋은 점 중 하나입니다. “self”이외의 객체 인스턴스에 대한 자리 표시자를 자유롭게 선택할 수 있습니다. 자기 예 :

class UserAccount():
    def __init__(self, user_type, username, password):
        self.user_type = user_type
        self.username = username
        self.password = encrypt(password)

    def get_password(self):
        return decrypt(self.password)

    def set_password(self, password):
        self.password = encrypt(password)

이제 ‘self’를 ‘its’로 바꿉니다.

class UserAccount():
    def __init__(its, user_type, username, password):
        its.user_type = user_type
        its.username = username
        its.password = encrypt(password)

    def get_password(its):
        return decrypt(its.password)

    def set_password(its, password):
        its.password = encrypt(password)

어느 것이 지금 더 읽을 수 있습니까?


답변

self는 객체의 멤버에 액세스하기위한 python 구문의 일부이므로이를 사용하는 것이 두렵습니다.