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")
자바에서는 퍼블릭/프라이빗/프로텍트 변수에 대해 배웠습니다.이러한 키워드는 클래스 밖에 있는 누구도 액세스할 수 없는 클래스 내의 변수를 원할 수 있기 때문에 의미가 있습니다.
왜 Python에서는 그것이 필요하지 않은가?
문화적이죠.Python에서는 다른 클래스의 인스턴스나 클래스 변수에 쓰지 않습니다.Java 에서는, 정말로 하고 싶은 경우, 같은 작업을 할 수 있는 것은 없습니다.결국, 클래스 자체의 소스를 항상 편집해 같은 효과를 얻을 수 있습니다.Python은 그러한 보안의 허세를 버리고 프로그래머에게 책임을 지도록 장려한다.실제로, 이것은 매우 잘 작동합니다.
로 개인 " "를 할 수 .__
PEP 8의 접두사. Python은 다음과 같은 변수의 이름을 망칩니다.__foo
이 때문에, 그것들을 포함한 클래스외의 코드에 간단하게 표시되지 않게 됩니다(Java의 보호를 회피할 수 있는 것처럼, 충분히 판단하면 회피할 수 있습니다).
「 」는_
prefix는 기술적으로 금지되지 않은 경우에도 멀리 떨어져 있는 것을 의미합니다.다른 클래스의 변수를 가지고 놀면 안 돼요__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)
if, if, if, if.A.printVar()
있는 할 수 .x
, 이 필드는 외부에서도 액세스 할 수 있습니다. A.printVar()
을 위해 그 안에 있는 ...결국, 기능은 재사용성을 위해 생성되며, 그 안에 있는 문장에 특별한 힘이 주어지지 않습니다.
컴파일러가 관련되어 있는 경우는 게임이 다릅니다(프라이버시는 컴파일러 수준의 개념입니다).액세스 제어 수식자가 있는 클래스 정의에 대해 알고 있기 때문에 컴파일 시에 규칙을 따르지 않을 경우 오류가 발생할 수 있습니다.
위의 많은 코멘트에서 올바르게 언급되었듯이 액세스 수정자의 주요 목적을 잊지 마십시오.코드 사용자가 변경되어야 할 것과 변경해서는 안 되는 것을 이해할 수 있도록 도와줍니다.개인 밭을 보면 함부로 손대지 않는다.그래서 Python에서는 _와 ___에 의해 쉽게 얻어지는 통사설탕이 대부분이다.
Python에는 C++나 Java와 같은 개인 변수가 없습니다.원하는 경우 언제든지 모든 멤버 변수에 액세스할 수 있습니다.그러나 Python에서는 클래스 멤버 변수를 노출하는 것이 나쁘지 않기 때문에 Python에서는 개인 변수가 필요하지 않습니다.멤버 변수를 캡슐화할 필요가 있는 경우 기존 클라이언트 코드를 중단하지 않고 나중에 "@property"를 사용하여 이를 수행할 수 있습니다.
파이썬에서는 메서드 또는 변수가 클래스의 퍼블릭 API의 일부로 간주되지 않으며 API의 이 부분이 다른 버전 간에 변경될 수 있음을 나타내기 위해 단일 언더스코어 "_"가 사용됩니다.이러한 메서드/변수를 사용할 수 있지만 이 클래스의 새 버전을 사용하면 코드가 끊어질 수 있습니다.
이중 밑줄 "_"은 "개인 변수"를 의미하지 않습니다.이 명령을 사용하여 "class local"이며 하위 클래스에서 쉽게 재정의할 수 없는 변수를 정의합니다.변수 이름이 엉망이 됩니다.
예를 들어 다음과 같습니다.
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의 _A_foobar.B클래스에서는 그것은 자기 자신으로 뭉개져 있다._B__foobar.따라서 모든 서브클래스는 부모 변수를 덮어쓰지 않고 자체 변수 __foobar를 정의할 수 있습니다.그러나 이중 밑줄로 시작하는 변수에 액세스할 수 있습니다.단, name-mangling을 사용하면 이 변수/메서드를 우발적으로 호출할 수 없습니다.
Pycon 2013의 Raymond Hettinger의 Python 클래스 개발 툴킷을 보시기 바랍니다.이 툴킷은 @property 및 "_" 인스턴스 변수를 사용해야 하는 이유와 방법을 보여줍니다.
공개변수를 공개하여 캡슐화할 필요가 있는 경우 @property를 사용할 수 있습니다.따라서 가장 간단한 솔루션부터 시작할 수 있습니다.특별한 이유가 없는 한 멤버 변수를 공개 상태로 둘 수 있습니다.다음은 예를 제시하겠습니다.
class Distance:
def __init__(self, meter):
self.meter = meter
d = Distance(1.0)
print(d.meter)
# prints 1.0
class Distance:
def __init__(self, meter):
# Customer request: Distances must be stored in millimeters.
# Public available internals must be changed.
# This would break client code in C++.
# This is why you never expose public variables in C++ or Java.
# However, this is python.
self.millimeter = meter * 1000
# In python we have @property to the rescue.
@property
def meter(self):
return self.millimeter *0.001
@meter.setter
def meter(self, value):
self.millimeter = value * 1000
d = Distance(1.0)
print(d.meter)
# prints 1.0
언더스코어 표기법에는 개인 변수의 변형이 있습니다.
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 decorator의 예로는 이 개념을 보다 밀접하게 구현한 것이 있지만 YMMV입니다.아마 메타를 사용하는 클래스 정의도 작성할 수 있을 것입니다.
앞서 설명한 바와 같이 변수 또는 메서드에 언더스코어를 붙이면 변수 또는 메서드가 개인임을 나타낼 수 있습니다.부족하다고.property
예를 제시하겠습니다하다
class Foo:
def __init__(self, bar):
self._bar = bar
@property
def bar(self):
"""Getter for '_bar'."""
return self._bar
해서 '', '아까', '아까', '', '아까', '', '아까', '아까', '아까', '아까', '아까', '아까', '아까', '아까', '아까', '아까',bar
는 실제로 ''을.bar
변수 자체보다는 기능하기 때문에 액세스할 수는 있지만 변경할 수는 없습니다. 정말 싶은 사람이 지, 약, 만, 만, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, 들, however, however, however, however, however, however, however, however, however,_bar
새로운 값을 할당합니다.여러 번 말한 바와 같이 사용자가 숨기려는 변수 및 메서드에 다른 사용자가 액세스하지 못하도록 할 확실한 방법은 없습니다. ,를 property
는 변수를 편집하지 않는다는 가장 명확한 메시지입니다. property
는, 다음의 설명에 따라서, 보다 복잡한 getter/setter/setter 액세스 패스에도 사용할 수 있습니다.https://docs.python.org/3/library/functions.html#property
Python은 두 개의 밑줄로 시작하는 식별자에 클래스 이름을 자동으로 추가하는 기능을 통해 개인 식별자를 제한적으로 지원합니다.이것은 프로그래머에게는 대부분 투명하지만, 이 방법으로 명명된 모든 변수를 개인 변수로 사용할 수 있습니다.
자세한 내용은 여기를 참조하십시오.
일반적으로 Python의 객체 방향 구현은 다른 언어에 비해 다소 원시적입니다.하지만 난 사실 이게 좋아개념적으로 매우 심플한 구현으로 역동적인 언어 스타일에 잘 맞습니다.
"자바에서는 공용/개인/보호 변수에 대해 배웠습니다."
"왜 python에서는 그것이 필요하지 않은가?"
같은 이유로 Java에서는 필요하지 않습니다.
private
★★★★★★★★★★★★★★★★★」protected
.
로서 Python의 를 발견했습니다.private
★★★★★★★★★★★★★★★★★」protected
매우 중요한 디자인 컨셉입니다.하지만 실제로 수만 줄의 Java와 Python에서 실제로 사용한 적은 없습니다.private
★★★★★★★★★★★★★★★★★」protected
.
왜 안 되나요?
제 질문은 "누구로부터 보호?"입니다.
우리 팀의 다른 프로그래머들?그들이 출처를 알아냈어사용자가 변경할 수 있는 경우 보호는 무엇을 의미?
다른 팀의 프로그래머들도?그들은 같은 회사에서 일한다.전화 한 통으로 소스를 얻을 수 있습니다.
클라이언트?그것은 (일반적으로) 고용인을 위한 프로그래밍이다.클라이언트(일반적으로)가 코드를 소유합니다.
그럼, 정확히 누구로부터 보호하고 있는 걸까요?
개인 변수를 사용하는 유일한 시간은 변수에 쓰거나 읽을 때 다른 작업을 수행해야 하는 경우이며, 따라서 세터 및/또는 게터를 강제로 사용해야 합니다.
다시 말하지만, 이것은 이미 말한 것처럼 문화로 돌아간다.저는 다른 클래스 변수를 읽고 쓰는 것이 자유로운 프로젝트를 해왔습니다.1개의 구현이 폐지되면 해당 기능을 사용하는 모든 코드 경로를 식별하는 데 훨씬 더 오랜 시간이 걸렸습니다.setters와 getters를 강제로 사용하는 경우 debug 문을 쉽게 작성하여 사용되지 않는 메서드가 호출되었음을 식별하고 이를 호출하는 코드 경로를 식별할 수 있습니다.
누구나 확장자를 쓸 수 있는 프로젝트에서는 업그레이드 시 모듈 파손을 최소한으로 유지하기 위해 일부 릴리스에서 삭제되는 권장되지 않는 방법을 사용자에게 통지하는 것이 중요합니다.
따라서 제 대답은 여러분과 동료들이 단순한 코드 세트를 유지한다면 클래스 변수를 항상 보호할 필요는 없다는 것입니다.확장 가능한 시스템을 작성하는 경우 코드를 사용하는 모든 확장에 의해 포착될 필요가 있는 코어에 변경이 가해질 때 반드시 필요합니다.
스레드를 "재수정"해서 죄송합니다.이것이 누군가에게 도움이 되었으면 합니다.
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 - 개발에 사용할 수 있는 리소스가 제한된 프로토타이핑 및 신속한 개발을 위한 도구일 뿐이기 때문에 일부 보호 수준이 python에 대해 그렇게 엄격하지 않습니다.클래스 멤버에서 "__"를 사용할 수 있지만 올바르게 작동하지만 충분하지 않습니다. 이러한 필드에 대한 각 액세스에는 이러한 문자가 포함됩니다.
또한 python OOP 컨셉은 완전하지 않고 smaltalk 또는 ruby가 순수 OOP 컨셉에 훨씬 가깝다는 것을 알 수 있습니다.C#이나 Java가 더 가깝습니다.
Python은 매우 좋은 도구입니다.그러나 이것은 단순화된 OOP 언어입니다.구문 및 개념적으로 단순화.python 존재의 주요 목표는 개발자들에게 매우 빠른 방식으로 높은 추상화 수준으로 읽기 쉬운 코드를 쓸 수 있는 가능성을 제공하는 것입니다.
소스 정보(접근 권한을 변경하여 Java 또는 C++와 같은 언어 캡슐화를 우회하는 경우): 소스가 항상 있는 것은 아닙니다.또, 있어도, 소스는 특정의 프로그래머만이 소스에 액세스 할 수 있는 시스템(프로패셔널 컨텍스트)에 의해서 관리됩니다.종종, 모든 프로그래머들은 특정 수업을 책임지고, 따라서 그가 무엇을 할 수 있고 할 수 없는지를 알고 있다.소스 매니저는 수정되는 소스도 잠그고 프로그래머의 접근 권한도 관리합니다.
그래서 저는 경험상 인간보다 소프트웨어를 더 신뢰합니다.따라서 관례는 좋지만 액세스 관리(실제 개인 변수) + 소스 관리와 같이 다중 보호 기능이 더 우수합니다.
Python은 처음이지만 C#과 JavaScript에 대한 경험이 있습니다.Python은 기능면에서 두 가지를 혼합한 느낌이다.JavaScript는 이 영역에서도 어려움을 겪고 있으며, 이 영역에서의 방법은 폐쇄를 만드는 것입니다.이렇게 하면 다른 개체를 반환하여 노출하지 않으려는 데이터에 액세스할 수 없습니다.
def print_msg(msg):
# This is the outer enclosing function
def printer():
# This is the nested function
print(msg)
return printer # returns the nested function
# Now let's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()
https://www.programiz.com/python-programming/closure
Python3 클래스 필드를 처리하는 방법은 다음과 같습니다.
Class MyClass:
def __init__(self, public_read_variable, private_variable):
self.public_read_variable_ = public_read_variable
self.__private_variable = private_variable
에 the i에액 i i i i i 。__private_variable
이 두 MyClass
★★★★★★★★★★★★★★★★★★.
읽기 액세스를 합니다.public_read_variable_
클래스 밖에 언더스코어를 1개 붙이지만 변수는 변경하지 않습니다.
my_class = MyClass("public", "private")
print(my_class.public_read_variable_) # OK
my_class.public_read_variable_ = 'another value' # NOT OK, don't do that.
언급URL : https://stackoverflow.com/questions/1641219/does-python-have-private-variables-in-classes
'programing' 카테고리의 다른 글
전처리 후 gcc가 C코드를 출력할 수 있습니까? (0) | 2022.10.22 |
---|---|
Python에서 날짜에 날짜 추가 (0) | 2022.10.22 |
Java가 이미지를 버퍼 이미지로 변환 (0) | 2022.10.22 |
python 요청 시간 초과.전체 응답 가져오기 (0) | 2022.10.22 |
wait는 비동기 기능에서만 유효합니다. (0) | 2022.10.22 |