문제

저는 Java 세계에서 왔으며 Bruce Eckels의 글을 읽고 있습니다. Python 3 패턴, 레시피 및 숙어.

클래스에 대해 읽는 동안 Python에서는 인스턴스 변수를 선언할 필요가 없다고 말합니다.생성자에서 그것들을 사용하면 굉장합니다. 거기에 있습니다.

예를 들면 다음과 같습니다.

class Simple:
    def __init__(self, s):
        print("inside the simple constructor")
        self.s = s

    def show(self):
        print(self.s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

그것이 사실이라면 클래스의 모든 객체는 Simple 변수의 값을 변경할 수 있습니다 s 수업 밖.

예를 들어:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

Java에서는 공개/비공개/보호 변수에 대해 배웠습니다.때때로 클래스 외부의 누구도 액세스할 수 없는 클래스의 변수를 원하기 때문에 이러한 키워드는 의미가 있습니다.

Python에서는 왜 이것이 필요하지 않습니까?

도움이 되었습니까?

해결책

문화적입니다. 파이썬에서는 다른 클래스의 인스턴스 또는 클래스 변수에 쓰지 않습니다. Java에서는 당신이 똑같이하는 것을 막을 수 없습니다. 진짜 결국, 당신은 항상 클래스 자체의 소스를 편집하여 동일한 효과를 달성 할 수 있습니다. Python은 보안의 척도를 떨어 뜨리고 프로그래머가 책임을 지도록 장려합니다. 실제로 이것은 매우 잘 작동합니다.

어떤 이유로 개인 변수를 모방하려면 언제든지 사용할 수 있습니다. __ 접두사 PEP 8. 파이썬은 같은 변수의 이름을 관리합니다 __foo 그들이 포함하는 클래스 밖에서 코드를 쉽게 볼 수 없도록 ~할 수 있다 당신처럼 충분히 결정되면 주위를 돌아 다니십시오. ~할 수 있다 작업하면 Java의 보호를 주위로 가져 가십시오).

같은 협약으로 _ 접두사는 의미합니다 기술적으로 그렇게하지 않더라도 멀리있어. 당신은 다른 클래스의 변수를 가지고 놀지 않습니다. __foo 또는 _bar.

다른 팁

Python의 개인 변수는 해킹입니다. 통역사는 의도적으로 변수를 이름을 바꿉니다.

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

이제 액세스하려고한다면 __var 클래스 정의 외부에서는 실패합니다.

 >>>x = A()
 >>>x.__var # this will return error: "A has no attribute __var"

 >>>x.printVar() # this gives back 123

그러나 당신은 이것으로 쉽게 도망 갈 수 있습니다.

 >>>x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

 >>>x._A__var = 456 # you now know the masked name of private variables
 >>>x.printVar() # this gives back 456

OOP의 방법이 다음과 같이 호출된다는 것을 알고있을 것입니다. x.printVar() => A.printVar(x), 만약에 A.printVar() 일부 필드에 액세스 할 수 있습니다 x,이 필드에도 액세스 할 수 있습니다 밖의 A.printVar()... 결국, 기능은 재사용 가능성을 위해 만들어졌으며 내부의 진술에 특별한 힘이 제공되지 않습니다.

컴파일러가 관련된 경우 게임이 다릅니다 (개인 정보는 컴파일러 레벨 개념입니다). 액세스 제어 수정자를 사용한 클래스 정의에 대해 알고 있으므로 컴파일 타임에 규칙을 따르지 않으면 오류가 발생할 수 있습니다.

위의 많은 의견에 의해 올바르게 언급 된 바와 같이, 액세스 수정 자의 주요 목표를 잊지 마십시오. 코드 사용자가 변경해야 할 사항과 예상되지 않은 내용을 이해하도록 돕는 것입니다. 개인 분야가 보이면 엉망이되지 않습니다. 따라서 대부분 파이썬에서 _ 및 __에 의해 쉽게 달성되는 구문 설탕입니다.

"Java에서는 공공/개인/보호 변수에 대해 배웠습니다."

"왜 파이썬에서는 그것이 필요하지 않습니까?"

같은 이유로, 그렇지 않습니다 필수의 자바에서.

자유롭게 사용할 수 있습니다 private 그리고 protected.

파이썬과 Java 프로그래머로서 나는 그것을 발견했습니다. private 그리고 protected 매우 중요한 디자인 개념입니다. 그러나 실질적인 문제로, 수만 줄의 자바와 파이썬에서 나는 결코 실제로 사용된 private 또는 protected.

왜 안 돼?

여기 내 질문이 "누구로부터 보호 받습니까?"

우리 팀의 다른 프로그래머? 그들은 출처가 있습니다. 보호 된 보호는 변경할 수있을 때 무엇을 의미합니까?

다른 팀의 다른 프로그래머? 그들은 같은 회사에서 일합니다. 그들은 전화로 소스를 얻을 수 있습니다.

고객? 직장-고용 프로그래밍 (일반적으로)입니다. 클라이언트 (일반적으로)는 코드를 소유합니다.

그렇다면 누가 - 정확하게 - 나는 그것을 보호하고 있습니까?

밑줄 규칙에는 개인 변수의 변형이 있습니다.

In [5]: class Test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:     

In [6]: x = Test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'Test' object has no attribute '__private_method'

미묘한 차이가 있지만 프로그래밍 패턴 이데올로기 적 순도를 위해 충분히 좋습니다.

@private 데코레이터에는 개념을보다 면밀히 구현하는 예가 있지만 ymmv. 아마도 메타를 사용하는 클래스 정의를 쓸 수도 있습니다.

Python은 개인 식별자에 대한 지원이 제한되어 있으며, 두 밑줄로 시작하는 모든 식별자에게 클래스 이름을 자동으로 전제하는 기능을 통해 제한적입니다. 이것은 대부분 프로그래머에게 투명하지만, 순 효과는이 방식으로 명명 된 변수를 개인 변수로 사용할 수 있다는 것입니다.

보다 여기 그것에 대한 자세한 내용.

일반적으로 Python의 객체 방향 구현은 다른 언어에 비해 약간 원시적입니다. 그러나 나는 실제로 이것을 즐긴다. 매우 개념적으로 간단한 구현이며 언어의 역동적 인 스타일과 잘 어울립니다.

앞에서 언급했듯이 변수 또는 메소드가 밑줄로 접두사를 접두사하여 비공개임을 나타낼 수 있습니다. 이것이 충분하다고 느끼지 않으면 언제든지 사용할 수 있습니다. property 데코레이터. 예는 다음과 같습니다.

class Foo:

    def __init__(self, bar):
        self._bar = bar

    @property
    def bar(self):
        """Getter for '_bar'."""
        return self._bar

이런 식으로, 누군가 또는 언급하는 것 bar 실제로 반환 값을 참조하고 있습니다 bar 변수 자체가 아닌 함수이므로 액세스 할 수 있지만 변경할 수 없습니다. 그러나 누군가가 정말로 원한다면 단순히 사용할 수 있습니다. _bar 새로운 가치를 지정하십시오. 반복적으로 말한 것처럼 누군가가 숨기고 싶은 변수와 방법에 액세스하는 것을 방해하는 확실한 방법은 없습니다. 그러나 사용 property 변수를 편집 할 수 없다는 것을 보낼 수있는 가장 명확한 메시지입니다. property 여기에 설명 된 바와 같이보다 복잡한 getter/setter/deleter 액세스 경로에도 사용할 수 있습니다. https://docs.python.org/3/library/functions.html#property

개인 변수를 사용하는 유일한 시간은 변수에 글을 쓰거나 읽을 때 다른 일을해야 할 때입니다. 따라서 세터 및/또는 getter의 사용을 강요해야합니다.

다시 언급 한 바와 같이 다시 문화로 간다. 나는 다른 수업 변수를 읽고 쓰는 것이 모두 무료 인 프로젝트를 진행하고 있습니다. 하나의 구현이 감가 상각되면 해당 기능을 사용한 모든 코드 경로를 식별하는 데 시간이 오래 걸렸습니다. 세터와 getters를 사용했을 때, 더 이상 사용되지 않은 방법이 호출되었음을 식별하기 위해 디버그 진술을 쉽게 작성할 수 있으며이를 호출하는 코드 경로를 확인할 수 있습니다.

누군가가 확장을 작성할 수있는 프로젝트에있을 때는 사용자에게 몇 개의 릴리스에서 사라질 더 이상 사용되지 않은 방법에 대해 알리므로 업그레이드시 모듈 파손을 최소로 유지하는 데 필수적입니다.

그래서 내 대답은; 귀하와 귀하의 동료가 간단한 코드 세트를 유지하는 경우 클래스 변수를 보호하는 것이 항상 필요한 것은 아닙니다. 확장 가능한 시스템을 작성하는 경우 코드를 사용하여 모든 확장자가 잡아야하는 코어 변경이 이루어질 때 필수적이됩니다.

개인 및 보호 개념은 매우 중요합니다. 그러나 Python- 개발에 이용할 수있는 제한된 자원을 갖춘 프로토 타이핑 및 신속한 개발 도구이므로 Python에서는 일부 보호 수준이 엄격하지 않은 이유입니다. 클래스 멤버에서 "__"를 사용할 수 있으며 제대로 작동하지만 충분히 잘 보이지 않습니다. 해당 필드에 대한 각 액세스에는 이러한 문자가 포함되어 있습니다.

또한 Python OOP 개념이 완벽하지 않다는 것을 알 수 있습니다. Smaltalk 또는 Ruby는 Pure OOP 개념에 훨씬 가깝습니다. C# 또는 Java조차도 더 가깝습니다.

파이썬은 매우 좋은 도구입니다. 그러나 그것은 단순화 된 OOP 언어입니다. 구문 적으로 개념적으로 단순화되었습니다. Python 존재의 주요 목표는 개발자에게 매우 빠른 방식으로 높은 추상화 수준으로 쉽게 읽을 수있는 코드를 작성할 수있는 가능성을 개발하는 것입니다.

스레드를 "부활"시켜서 죄송합니다. 하지만 이것이 누군가에게 도움이 되기를 바랍니다.

Python3에서 Java와 같이 클래스 속성을 "캡슐화"하려는 경우 다음과 같이 동일한 작업을 수행할 수 있습니다.

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

이를 인스턴스화하려면 다음을 수행하십시오.

ss = Simple("lol")
ss.show()

참고 사항: print(ss.__s) 오류가 발생합니다.

실제로 Python3은 전역 속성 이름을 난독화합니다.Java에서와 같이 이를 "개인" 속성처럼 전환합니다.속성의 이름은 여전히 ​​전역적이지만 다른 언어의 비공개 속성처럼 접근할 수 없는 방식입니다.

그러나 두려워하지 마십시오.그것은 중요하지 않습니다.그것은 일도합니다.;)

Python에는 C ++ 또는 Java와 같은 개인 변수가 없습니다. 원하는 경우 언제든지 멤버 변수에 액세스 할 수 있습니다. 그러나 파이썬에서는 개인 변수가 필요하지 않습니다. 파이썬에서는 클래스 멤버 변수를 노출시키는 것이 나쁘지 않기 때문입니다. 회원 변수를 캡슐화 해야하는 경우 기존 클라이언트 코드를 깨지 않고 나중에 "@property"를 사용하여이를 수행 할 수 있습니다.

파이썬에서 단일 밑줄 "_"는 메소드 또는 변수가 클래스의 공개 API의 일부로 간주되지 않으며 API 의이 부분이 다른 버전간에 변경 될 수 있음을 나타내는 데 사용됩니다. 이 메소드/변수를 사용할 수 있지만이 클래스의 최신 버전을 사용하면 코드가 중단 될 수 있습니다.

이중 밑줄 "__"는 "개인 변수"를 의미하지 않습니다. 이를 사용하여 "클래스 로컬"이며 서브 클래스로 쉽게 지나칠 수없는 변수를 정의합니다. 변수 이름을 관리합니다.

예를 들어:

class A(object):
    def __init__(self):
        self.__foobar = None # will be automatically mangled to self._A__foobar

class B(A):
    def __init__(self):
        self.__foobar = 1 # will be automatically mangled to self._B__foobar

self .__ foobar의 이름은 자동으로 self._a__foobar 클래스 A의 클래스 B에서 엉망이됩니다. 클래스 B에서는 self._b__foobar로 엉망입니다. 따라서 모든 서브 클래스는 부모 변수를 무시하지 않고 자체 변수 __foobar를 정의 할 수 있습니다. 그러나 이중 밑줄로 시작하는 변수에 액세스하지 못하게하는 것은 없습니다. 그러나 이름 랭킹은이 변수 /방법을 우연히 호출하지 못하게합니다.

PYCON 2013의 Raymond Hettingers가 "Pythons Class Development Toolkit"(YouTube에서 사용할 수 있어야 함)의 대화를 보는 것이 좋습니다.이 예제는 @Property 및 "__"-인스턴스 변수를 사용해야하는 이유와 방법을 제공합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top