[python] 인스턴스 변수와 Python의 클래스 변수

런타임에 인스턴스가 하나만 필요한 Python 클래스가 있으므로 인스턴스가 아닌 클래스 당 한 번만 속성을 갖는 것으로 충분합니다. 둘 이상의 인스턴스가있는 경우 (발생하지 않음) 모든 인스턴스는 동일한 구성을 가져야합니다. 다음 옵션 중 어느 것이 더 낫거나 더 “유용한”Python이 될지 궁금합니다.

클래스 변수 :

class MyController(Controller):

  path = "something/"
  children = [AController, BController]

  def action(self, request):
    pass

인스턴스 변수 :

class MyController(Controller):

  def __init__(self):
    self.path = "something/"
    self.children = [AController, BController]

  def action(self, request):
    pass



답변

어쨌든 인스턴스가 하나만있는 경우 모든 변수를 인스턴스별로 만드는 것이 가장 좋습니다. 단순히 액세스 (조금) 속도가 빨라지기 때문입니다 (클래스에서 인스턴스로의 “상속”으로 인해 “조회”수준이 하나 적음). 그리고이 작은 이점에 대해 평가할 단점이 없습니다.


답변

MikeAlex의 충고를 더 반영 하고 나만의 색상을 추가합니다.

인스턴스 속성을 사용하는 것이 일반적입니다 … 더 관용적 인 Python입니다. 클래스 속성은 사용 사례가 구체적이기 때문에 많이 사용되지 않습니다. 정적 및 클래스 메서드와 “일반”메서드의 경우에도 마찬가지입니다. 그것들은 특정한 사용 사례를 다루는 특별한 구조이고, 그렇지 않으면 파이썬 프로그래밍의 모호한 부분을 알고 있음을 보여주고 싶어하는 비정상적인 프로그래머가 만든 코드입니다.

Alex는 자신의 답변에서 조회 수준이 한 단계 줄어들 기 때문에 액세스가 (조금) 더 빨라질 것이라고 언급했습니다. 아직 이것이 어떻게 작동하는지 모르는 사람들을 위해 더 자세히 설명하겠습니다. 변수 액세스와 매우 유사하며 검색 순서는 다음과 같습니다.

  1. 지역 주민
  2. 비 현지인
  3. 글로벌
  4. 내장

속성 액세스의 경우 순서는 다음과 같습니다.

  1. 수업
  2. MRO에 의해 결정된 기본 클래스 (메소드 확인 순서)

두 기술 모두 “인사이드 아웃 (inside-out)”방식으로 작동합니다. 즉, 대부분의 로컬 객체가 먼저 확인 된 다음 외부 레이어가 연속적으로 확인됩니다.

위의 예에서 path속성을 찾고 있다고 가정 해 보겠습니다 . ” self.path” 와 같은 참조를 발견하면 Python은 먼저 인스턴스 속성에서 일치 항목을 찾습니다. 실패하면 개체가 인스턴스화 된 클래스를 확인합니다. 마지막으로 기본 클래스를 검색합니다. Alex가 말했듯이 인스턴스에서 속성이 발견되면 다른 곳을 볼 필요가 없으므로 약간의 시간이 절약됩니다.

그러나 클래스 속성을 고집하는 경우 추가 조회가 필요합니다. 또는 , 다른 대안은, 예를 들어, 클래스 대신 인스턴스를 통해 객체를 참조하는 MyController.path대신 self.path. 이것은 지연된 조회를 우회하는 직접 조회이지만 alex가 아래에서 언급했듯이 전역 변수이므로 저장할 것이라고 생각했던 비트를 잃게됩니다 ([global] 클래스 이름에 대한 로컬 참조를 생성하지 않는 한 ).

결론은 대부분의 경우 인스턴스 속성을 사용해야한다는 것입니다. 그러나 클래스 속성이 작업에 적합한 도구 인 경우가 있습니다. 두 가지를 동시에 사용하는 코드는 가장 많은 노력이 필요합니다 .을 사용하면 동일한 이름의 클래스 속성에 대한 self인스턴스 속성 개체와 섀도우 액세스 만 얻을 수 있기 때문 입니다. 이 경우 속성을 참조하려면 클래스 이름으로 속성 액세스 를 사용해야 합니다.


답변

확실하지 않은 경우 인스턴스 속성이 필요할 수 있습니다.

클래스 속성은 의미가있는 특수한 경우에 가장 적합합니다. 매우 일반적인 사용 사례는 방법뿐입니다. 아니다 드문 클래스 인스턴스 (당신은 또한에서 액세스하려면이 유일한 이점은 비록 알 필요가 읽기 전용 상수 속성을 사용하여 외부 클래스),하지만 당신은 확실히 그들에게 어떤 상태를 저장에 대해 신중해야 , 그것은 당신이 원하는 것은 거의 없습니다. 인스턴스가 하나만 있더라도 다른 클래스처럼 클래스를 작성해야합니다. 이는 일반적으로 인스턴스 속성을 사용하는 것을 의미합니다.


답변

Python에서 클래스 변수에 액세스하는 성능에 대한 동일한 질문 -@Edward Loper에서 수정 한 코드

로컬 변수는 가장 빠르게 액세스 할 수 있으며 모듈 변수, 클래스 변수, 인스턴스 변수 순으로 연결됩니다.

다음에서 변수에 액세스 할 수있는 4 가지 범위가 있습니다.

  1. 인스턴스 변수 (self.varname)
  2. 클래스 변수 (Classname.varname)
  3. 모듈 변수 (VARNAME)
  4. 지역 변수 (varname)

시험:

import timeit

setup='''
XGLOBAL= 5
class A:
    xclass = 5
    def __init__(self):
        self.xinstance = 5
    def f1(self):
        xlocal = 5
        x = self.xinstance
    def f2(self):
        xlocal = 5
        x = A.xclass
    def f3(self):
        xlocal = 5
        x = XGLOBAL
    def f4(self):
        xlocal = 5
        x = xlocal
a = A()
'''
print('access via instance variable: %.3f' % timeit.timeit('a.f1()', setup=setup, number=300000000) )
print('access via class variable: %.3f' % timeit.timeit('a.f2()', setup=setup, number=300000000) )
print('access via module variable: %.3f' % timeit.timeit('a.f3()', setup=setup, number=300000000) )
print('access via local variable: %.3f' % timeit.timeit('a.f4()', setup=setup, number=300000000) )

결과:

access via instance variable: 93.456
access via class variable: 82.169
access via module variable: 72.634
access via local variable: 72.199


답변