Program Tip

Python의 비공개 멤버

programtip 2020. 11. 30. 19:46
반응형

Python의 비공개 멤버


Python에서 메서드와 데이터 멤버를 비공개로 만들려면 어떻게해야합니까? 아니면 Python이 비공개 멤버를 지원하지 않습니까?


9.6. 개인 변수

객체 내부에서만 액세스 할 수없는 "비공개"인스턴스 변수는 Python에 존재하지 않습니다. 그러나 대부분의 Python 코드가 따르는 규칙이 있습니다. 밑줄이 붙은 이름 (예 : _spam)은 API의 비공개 부분으로 처리되어야합니다 (함수, 메서드 또는 데이터 멤버인지 여부). . 구현 세부 사항으로 간주되어야하며 예고없이 변경 될 수 있습니다.

클래스 전용 멤버에 대한 유효한 사용 사례가 있기 때문에 (즉, 하위 클래스에서 정의한 이름과 이름의 이름 충돌을 방지하기 위해) 이름 맹 글링이라는 메커니즘에 대한 지원이 제한됩니다. __spam 형식의 식별자 (최소 2 개의 선행 밑줄, 최대 1 개의 후행 밑줄)는 텍스트로 대체됩니다 _classname__spam. 여기서 classname은 선행 밑줄이 제거 된 현재 클래스 이름입니다. 이 맹 글링은 클래스 정의 내에서 발생하는 한 식별자의 구문 위치에 관계없이 수행됩니다.

따라서, 예를 들어 ,

class Test:
    def __private_symbol(self):
        pass
    def normal_symbol(self):
        pass

print dir(Test)

다음을 출력합니다.

['_Test__private_symbol', 
'__doc__', 
'__module__', 
'normal_symbol']

__private_symbol개인 메서드로 간주되어야하지만을 통해 액세스 할 수 있습니다 _Test__private_symbol.


다른 답변은 기술적 세부 사항을 제공합니다. 한편으로는 Python과 C ++ / Java와 같은 언어 간의 철학 차이를 강조하고 싶습니다 (귀하의 질문에 따라 익숙하다고 생각합니다).

파이썬 (그리고 그 문제에 대한 Perl)의 일반적인 태도는 속성의 '프라이버시'가 컴파일러 / 인터프리터에 의한 철조망이 아니라 프로그래머에 대한 요청이라는 것입니다. 이 아이디어는 이 메일에 잘 요약되어 있으며 프로그래머가 내부에 개입하지 않을 책임이 있다고 '가정'하기 때문에 종종 "우리는 모두 동의하는 성인"이라고합니다. 선행 밑줄은 속성이 내부라는 정중 한 메시지 역할을합니다.

당신이 다른 한편, 만약 않는 일부 응용 프로그램의 내부에 액세스하려면 당신은 그렇게 할 수있는 좋은 방법입니다 무료 (주목할만한 예는 pydoc이 같은 문서 발전기이다). 무거운 짐 당신이 무슨 일을하는지 알고 당신이 일을 어떻게 강제로 언어를 제대로보다는 그것을 할 수있는 프로그래머로 당신에 그것의 방법을.


privatePython에는 다른 액세스 보호 메커니즘 이 없습니다 . 특정 속성에 액세스해서는 안된다는 것을 클래스 사용자에게 알리기 위해 Python 스타일 가이드문서화 된 규칙이 있습니다 .

  • _single_leading_underscore : 약한 "내부 사용"표시기. 예를 들어 from M import *이름이 밑줄로 시작하는 개체를 가져 오지 않습니다.

  • single_trailing_underscore_ : 파이썬 키워드와의 충돌을 피하기 위해 관례에 의해 사용됩니다. Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore : 클래스 속성의 이름을 지정할 때 이름 변경을 호출합니다 (FooBar 클래스 내에서 __boo는 _FooBar__boo가됩니다. 아래 참조).


Python 함수, 클래스 메소드 또는 속성의 이름이 두 개의 밑줄로 시작하지만 (끝나지 않는) 경우 개인용입니다. 다른 모든 것은 공개됩니다. Python에는 보호 된 클래스 메서드의 개념이 없습니다 (자체 클래스 및 하위 클래스에서만 액세스 가능). 클래스 메서드는 private (자체 클래스에서만 액세스 가능) 또는 public (어디에서나 액세스 가능)입니다.

파이썬으로 뛰어 들기


파이썬은 프라이버시를 직접 지원하지 않습니다. 프로그래머는 외부에서 속성을 수정하는 것이 안전한시기를 알아야하지만 어쨌든 파이썬을 사용하면 약간의 트릭으로 사적인 것을 얻을 수 있습니다. 이제 개인이 무엇이든 비공개로 할 수 있는지 여부를 살펴 보겠습니다.

클래스 Person (객체) :

    def __priva (self) :
        print "I am Private"

    def publ (self) :
        print "나는 공개입니다"

    def callpriva (self) :
        self .__ priva ()

이제 실행할 때 :

>>> p = Person ()
>>> p.publ ()
 나는 공개
>>> p .__ priva ()
역 추적 (가장 최근 호출 마지막) :
  파일 "", 줄 1, in 
    p .__ priva ()
AttributeError : 'Person'개체에 '__priva'속성이 없습니다.
#Explanation : 여기서는 private method를 직접 가져올 수 없습니다.
>>> p.callpriva ()
나는 사립이다
# 설명 : 여기서 우리는 클래스 내부의 private 메서드에 액세스 할 수 있습니다.

그러면 누군가가 그 변수에 액세스 할 수있는 방법 ???
다음과 같이 할 수 있습니다.

>>> p._Person__priva
나는 사립이다

와우, 실제로 파이썬이 이중 밑줄로 시작하는 변수를 가져 오는 경우 시작 부분에 밑줄 하나와 클래스 이름을 추가하여 "번역"됩니다.

참고 : 이 이름을 변경하고 싶지 않지만 다른 개체에 대한 신호를 계속 보내려면 초기 밑줄이있는 단일 초기 밑줄 이름을 별표가있는 가져 오기와 함께 가져올 수 없습니다 (모듈 가져 오기 *에서).
예 :

# test.py
def hello () :
    "안녕하세요"인쇄
def _hello () :
    "Hello private"인쇄

# ----------------------
# test2.py
테스트 가져 오기에서 *
hello () 인쇄
print _hello ()

출력->

여보세요
역 추적 (가장 최근 호출 마지막) :
  파일 "", 줄 1, in 
NameError : '_hello'이름이 정의되지 않았습니다.

이제 _hello를 수동으로 호출하면됩니다.

# test2.py
테스트에서 가져 오기 _hello, hello
hello () 인쇄
print _hello ()

출력->

여보세요
안녕하세요 개인

마지막으로, 파이썬은 실제로 동등한 개인 정보 보호 기능을 지원하지 않지만 단일 및 이중 초기 밑줄은 어느 정도는 두 가지 수준의 개인 정보 보호를 제공합니다.


이것은 작동 할 수 있습니다.

import sys, functools

def private(member):
    @functools.wraps(member)
    def wrapper(*function_args):
      myself = member.__name__
      caller = sys._getframe(1).f_code.co_name
      if (not caller in dir(function_args[0]) and not caller is myself):
         raise Exception("%s called by %s is private"%(myself,caller))
      return member(*function_args)
    return wrapper

class test:
   def public_method(self):
      print('public method called')

   @private
   def private_method(self):
      print('private method called')

t = test()
t.public_method()
t.private_method()

이것은 다소 긴 대답이지만 여기서 실제 문제의 근원 인 가시성의 범위에 도달한다고 생각합니다. 내가 이걸 훑어 보는 동안 그냥 거기에 기다려!

Simply importing a module need not necessarily give the application developer access to all of its classes or methods; if I can't actually SEE the module source code how will I know what's available? Some one (or some THING) has to tell me what I can do and explain how to use those features I'm allowed to use, otherwise the whole thing is useless to me.

Those developing higher-level abstractions based on fundamental classes and methods via imported modules are presented with a specification DOCUMENT -- NOT the actual source code.

The module spec describes all the features intended to be visible to the client developer. When dealing with large projects and software project teams, the actual implementation of a module should ALWAYS remain hidden from those using it -- it's a blackbox with an interface to the outside world. For OOD purists, I believe the techie terms are "decoupling" and "coherence". The module user need only know the interface methods without being burden with the details of implementation.

A module should NEVER be changed without first changing its underlying spec document, which may require review / approval in some organizations prior to changing the code.

As hobby programmer (retired now), I start a new module with the spec doc actually written out as a giant comment block at the top of the module, this will be the part the user actually sees in the spec library. Since it's just me, I've yet to set up a library, but it would be easy enough to do.

Then I begin coding by writing the various classes and methods but without functional bodies -- just null print statements like "print()" -- just enough to allow the module to compile without syntax errors. When this step is complete I compile the completed null-module -- this is my spec. If I were working on a project team, I would present this spec/interface for review & commentary before proceeding with fleshing out the body.

I flesh out the bodies of each method one at a time and compile accordingly, ensuring syntax errors are fixed immediately on-the-fly. This is also a good time to start writing a temporary "main" execution section at the bottom to test each method as you code it. When the coding/testing are complete, all of the test code is commented out until you need it again should updates become necessary.

In a real-world development team, the spec comment block would also appear in a document control library, but that's another story. The point is: you, as the module client, see only this spec and NOT the source code.

PS: long before the beginning of time, I worked in the defense aerospace community and we did some pretty cool stuff, but things like proprietary algorithms and sensitive systems control logic were tightly vaulted and encrypted in super-duper secure software libraries. We had access to module / package interfaces but NOT the blackbox implementation bodies. There was a document management tool that handled all system-level designs, software specs, source code and test records -- it was all synched together. The government had strict requirements software quality assurance standards. Anyone remember a language called "Ada"? That's how old I am!


I use Python 2.7 and 3.5. I wrote this code:

class MyOBject(object):
    def __init__(self):
        self.__private_field = 10


my_object = MyOBject()
print(my_object.__private_field)

ran it and got:

AttributeError: 'MyOBject' object has no attribute '__private_field'

Please see: https://www.tutorialsteacher.com/python/private-and-protected-access-modifiers-in-python


if you want to make a methods or data members private in Python, use __setattr __

class Number:
    def __init__(self,value):
        self.my_private = value

    def __setattr__(self, my_private, value):
        # the default behavior
        # self.__dict__[my_private] = value
        raise Exception("can't access private member-my_private")


def main():
    n = Number(2)
    print(n.my_private)

if __name__ == '__main__': 
    main()

참고URL : https://stackoverflow.com/questions/2064202/private-members-in-python

반응형