파이썬에서 "클래스 메소드"와 "인스턴스 메소드"란 무엇입니까?


37

채팅과 관련된 질문 (질문 자체는 이것과 관련이 없음)과 관련하여 토론이 있었는데, 파이썬을 전혀 알지 못할 수도 있음이 밝혀졌습니다.

제 생각에는 언어마다 용어가 다르지만 일반적으로 함수를 다음과 같이 분류 할 수 있습니다.

  • [무료] 기능
  • 정적 메소드 / 정적 멤버 함수
  • 비 정적 메소드 / 비 정적 멤버 함수

분명히 파이썬에는 위의 범주에 맞지 않는 또 다른 종류의 함수가 있습니다. 하나는 메소드이지만 "클래스를 몰랐습니다".

파이썬에서 "클래스 메소드"와 "인스턴스 메소드"란 무엇입니까?


1
채팅 토론에 관심이있는 사람은 여기에서 시작하십시오. chat.stackexchange.com/transcript/message/26479002#26479002
yannis

1
IMO 더 나은 답변은 다른 stackexchange 웹 사이트에서 제공합니다 : stackoverflow.com/questions/136097/…
Trevor Boyd Smith

참고로 링크는 허용 된 하단에 제공되지만 ... 많은 사람들이 링크를 놓치거나 절대 도달하지 않을 것이라고 생각합니다. 그래서 여기에 복사했습니다.
Trevor Boyd Smith

답변:


49

짧은 대답

  • 인스턴스 메소드는 인스턴스 (및 그 클래스에서)를 알고 있습니다.
  • 클래스 메소드는 클래스를 알고 있습니다
  • 정적 메소드는 클래스 나 인스턴스를 모른다

긴 대답

수업 방법

클래스 메소드는 전체 클래스에 속한 하나입니다. 인스턴스가 필요하지 않습니다. 대신 클래스가 첫 번째 인수로 자동 전송됩니다. 클래스 메소드는 @classmethod데코레이터 로 선언됩니다 .

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

class Foo(object):
    @classmethod
    def hello(cls):
        print("hello from %s" % cls.__name__)
Foo.hello()
-> "Hello from Foo"
Foo().hello()
-> "Hello from Foo"

인스턴스 메소드

반면, 인스턴스 메소드 에는 인스턴스를 호출하기 위해 인스턴스가 필요하며 데코레이터가 필요하지 않습니다. 이것은 가장 일반적인 유형의 방법입니다.

class Foo(object):
    def hello(self):
        print("hello from %s" % self.__class__.__name__)
Foo.hello()
-> TypeError: hello() missing 1 required positional argument: 'self'

(참고 : 위의 내용은 python3이며 python2의 경우 약간 다른 오류가 발생합니다)

정적 메소드

정적 메서드는 클래스 메소드와 유사하지만, 자동 매개 변수로 클래스 객체를받지 않습니다. @staticmethod데코레이터 를 사용하여 작성됩니다 .

class Foo(object):
    @staticmethod
    def hello(cls):
        print("hello from %s" % cls.__name__)

Foo.hello()
-> TypeError: hello() missing 1 required positional argument: 'cls'

설명서 링크

다음은 관련 python3 문서에 대한 링크입니다.

데이터 모델 문서는 클래스 메소드와 정적 방법의 차이에 대해 할 말이이있다 :

정적 메소드 객체 정적 메소드 객체는 함수 객체를 위에서 설명한 메소드 객체로 변환하지 않는 방법을 제공합니다. 정적 메소드 객체는 다른 객체, 일반적으로 사용자 정의 메소드 객체를 감싸는 래퍼입니다. 정적 메소드 오브젝트가 클래스 또는 클래스 인스턴스에서 검색 될 때 실제로 리턴 된 오브젝트는 랩핑 된 오브젝트이며, 추가 변환이 적용되지 않습니다. 정적 메소드 오브젝트는 일반적으로 랩핑하는 오브젝트이지만 호출 할 수는 없습니다. 정적 메소드 객체는 내장 staticmethod () 생성자에 의해 생성됩니다.

클래스 메서드 개체 정적 메서드 개체와 같은 클래스 메서드 개체는 다른 개체 주위의 래퍼로, 해당 개체가 클래스 및 클래스 인스턴스에서 검색되는 방식을 변경합니다. 이러한 검색시 클래스 메소드 오브젝트의 작동은 위에서 "사용자 정의 메소드"에 설명되어 있습니다. 클래스 메소드 객체는 내장 classmethod () 생성자에 의해 생성됩니다.

관련 질문


4
@ LightnessRacesinOrbit : 정적 메소드가 파이썬에서 특히 자주 사용되는 것은 아니라고 생각합니다. 내 시스템을 임의의 샘플로 사용하여 내가 설치 한 모든 패키지를 검색 할 때 모든 메소드 중 약 1 %만이 정적 메소드입니다 (솔직히 예상했던 것 이상이었습니다).
Bryan Oakley

1
"정적 방법"은 일반적으로 코드 냄새이며 Gogole Python 스타일 가이드와 같이 권장하지 않습니다.
9000

3
서브 클래스에주의를 기울이면 대답이 더 좋을 것이라고 생각합니다. 이는 클래스 메소드가 유용성을 얻는 곳입니다.
Winston Ewert

1
@ user2357112 :의 모든 인스턴스 "^ def("를 계산 한 다음의 모든 인스턴스를 계산했습니다 @staticmethod. 매우 비 과학적이지만 아마도 야구장 안에 있었을 것입니다.
Bryan Oakley

2
@Kashyap : TL; DR은 첫 번째 단락에 적용됩니다. 나는 그것이 바닥보다 상단에서 더 잘 작동한다고 생각합니다.
Bryan Oakley

8

파이썬에서 "클래스 메소드"와 "인스턴스 메소드"란 무엇입니까?

  • "인스턴스 방법"은 인스턴스에 포함 된 정보를 사용하여 반환 할 값 (또는 어떤 부작용)을 파악합니다. 이들은 매우 일반적입니다.

  • "클래스 메소드"는 클래스 (및 해당 클래스의 인스턴스가 아닌)에 대한 정보를 사용하여 수행하는 작업에 영향을줍니다 (일반적으로 대체 생성자로 새 인스턴스를 작성하는 데 사용되므로 매우 일반적이지 않습니다).

  • "정적 메서드"는 클래스 또는 인스턴스에 대한 정보를 사용하여 수행하는 작업을 계산하지 않습니다. 편의상 보통 수업 시간에 있습니다. (따라서 이것도 흔하지 않습니다.)

X의 기능

수학 클래스를 기억하십시오. "y는 x의 함수 f(x)입니까?" 코드로 적용 해 봅시다 :

y = function(x)

상기 암시이다 때문에 x변경 될 y때 변경 될 수 x변경. 이것이 " y는 " 의 함수입니다 x.

무엇을 할 y때 일 z이다 1? 2? 'FooBarBaz'?

y의 함수가 아니다 z, 그래서 z아무것도 할 수없는 우리의 가정 기능의 결과에 영향을 줄 function수있는 순수한 기능을. ( z글로벌 변수로 액세스 하면 순수한 기능이 아닙니다. 이것이 기능적 순도를 의미합니다.)

다음 설명을 읽을 때 위의 사항을 명심하십시오.

인스턴스 메소드

인스턴스 메소드는 함수 인 함수 인스턴스 . 이 함수는 인스턴스를 암시 적으로 인수로 받아들이고 함수의 인스턴스는 함수의 출력을 결정하는 데 사용됩니다.

인스턴스 메소드의 내장 예제는 str.lower입니다.

>>> 'ABC'.lower()
'abc'

str.lower 문자열의 인스턴스에서 호출되고 인스턴스에 포함 된 정보를 사용하여 반환 할 새 문자열을 찾습니다.

수업 방법 :

파이썬에서는 모든 것이 객체라는 것을 기억하십시오. 이것은 클래스가 객체이고 함수에 인수로 전달 될 수 있음을 의미합니다.

클래스 메소드는 함수 인 함수 클래스 . 그것은 클래스를 그것에 대한 인수로 받아들입니다.

내장 된 예는 dict.fromkeys다음과 같습니다.

>>> dict.fromkeys('ABC')
{'C': None, 'B': None, 'A': None}

이 함수는 암시 적으로 자체 클래스를 알고 있으며 클래스를 사용하여 함수의 출력에 영향을 미치고 iterable에서 해당 클래스의 새 클래스를 작성합니다. OrderedDict는 동일한 방법을 사용할 때이를 보여줍니다.

>>> from collections import OrderedDict
>>> OrderedDict.fromkeys('ABC')
OrderedDict([('A', None), ('B', None), ('C', None)])

클래스 메소드는 클래스에 대한 정보 (및 해당 클래스의 인스턴스가 아님)를 사용하여 리턴 할 클래스 유형에 영향을줍니다.

정적 방법

"클래스를 모른다"는 메소드를 언급했다. 이것은 파이썬에서 정적 메소드이다. 단지 클래스 객체에 편의를 위해 첨부됩니다. 선택적으로 다른 모듈에서 별도의 함수일 수 있지만 호출 서명은 동일합니다.

정적 메소드는 클래스 나 객체의 함수가 아닙니다.

정적 메소드의 내장 예제는 Python 3의 str.maketrans입니다.

>>> str.maketrans('abc', 'bca')
{97: 98, 98: 99, 99: 97}

몇 가지 인수가 주어지면 클래스의 기능이 아닌 사전을 만듭니다.

str전역 네임 스페이스에서 항상 사용할 수 있기 때문에 편리하므로 translate 함수와 함께 쉽게 사용할 수 있습니다.

>>> 'abracadabra'.translate(str.maketrans('abc', 'bca'))
'bcrbabdbcrb'

Python 2에서는 string모듈 에서 액세스해야 합니다.

>>> 'abracadabra'.translate(str.maketrans('abc', 'bca'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'str' has no attribute 'maketrans'
>>> import string
>>> 'abracadabra'.translate(string.maketrans('abc', 'bca'))
'bcrbabdbcrb'

class AClass(object):
    """In Python, a class may have several types of methods: 
    instance methods, class methods, and static methods
    """

    def an_instance_method(self, x, y, z=None):
        """this is a function of the instance of the object
        self is the object's instance
        """
        return self.a_class_method(x, y)

    @classmethod
    def a_class_method(cls, x, y, z=None):
        """this is a function of the class of the object
        cls is the object's class
        """
        return cls.a_static_method(x, y, z=z)

    @staticmethod
    def a_static_method(x, y, z=None):
        """this is neither a function of the instance or class to 
        which it is attached
        """
        return x, y, z

인스턴스화하자 :

>>> instance = AClass()

이제 인스턴스는 모든 메소드를 호출 할 수 있습니다.

>>> instance.an_instance_method('x', 'y')
('x', 'y', None)
>>> instance.a_static_method('x', 'y')
('x', 'y', None)
>>> instance.a_class_method('x', 'y')
('x', 'y', None)

그러나 클래스는 일반적으로 인스턴스 메소드를 호출하려는 것이 아니지만 다른 메소드를 호출해야합니다.

>>> AClass.a_class_method('x', 'y')
('x', 'y', None)
>>> AClass.a_static_method('x', 'y')
('x', 'y', None)
>>> AClass.an_instance_method('x', 'y')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an_instance_method() missing 1 required positional argument: 'y'

인스턴스 메소드를 호출하려면 인스턴스를 명시 적으로 전달해야합니다.

>>> AClass.an_instance_method(instance, 'x', 'y')
('x', 'y', None)

"이것은 Python의 정적 메소드입니다. 클래스 객체에 편의를 위해 첨부 된 것입니다. 선택적으로 다른 모듈에서 별도의 함수일 수 있지만 호출 서명은 동일합니다." 편리함보다 더 혼란스러워 보입니다. 본문에 해당 클래스에 대한 개념이 없으면 함수를 클래스에 첨부하는 이유는 무엇입니까?
Monica와의 가벼움 경주

@LightnessRacesinOrbit 각 포인트에 대해 자세히 설명했습니다
Aaron Hall

개인적으로, 내가 항상 살펴본 방식은 인스턴스 메소드가 특정 인스턴스의 작업이고, 클래스 메소드는 일종의 생성자 (편의상, 그와 비슷한 MyClass(1,2,3)것이 아니라 MyClass.get_special(1,2,3))와 정적 메소드라는 것입니다. 어쨌든 혼자 서있을 수있는 정상적인 기능입니다.
Zizouz212

예, 클래스 메소드는 일반적으로 대체 생성자 (위의 dict.fromkeys 예제 참조, pandas.DataFrame 소스 코드 참조)에 사용되지만 이는 정의적인 특성이 아닙니다. 때로는 인스턴스에 액세스하지 않고 메소드에서 클래스 수준에 저장된 데이터에 액세스하기 만하면됩니다. type (self) (또는 더 나쁜 self .__ class__)을 호출하고 인스턴스 메소드에서 self를 직접 사용하지 않는 경우 클래스 메소드로 간주해야한다는 좋은 신호입니다. 클래스 메소드에는 인스턴스가 필요하지 않기 때문에 단위 테스트가 더 쉽습니다.
Aaron Hall

4
  • "인스턴스 메소드"는 인스턴스 오브젝트를 첫 번째 매개 변수로 전달하는 메소드이며,이를 규칙에 따라 호출 self합니다. 이것이 기본값입니다.

  • "정적 방법"은 초기 self매개 변수가 없는 방법 입니다. 이것은 @staticmethod 데코레이터로 구현됩니다 .

  • "클래스 메소드"는 초기 매개 변수가 인스턴스 오브젝트가 아니라 클래스 오브젝트 ( "클래스 오브젝트"가 무엇인지 에 대한 파이썬 문서의이 부분 참조 ) 인 메소드이며, 규칙에 의해 호출 cls됩니다. 이것은 @classmethod 데코레이터로 구현됩니다 .

C / C ++ / etc에서 "정적 메소드"라는 용어의 일반적인 사용법은 Python "정적"및 Python "클래스"메소드 모두에 적용됩니다. 두 가지 유형의 메소드 모두 인스턴스에 대한 참조가 없기 때문입니다. C / C ++ / etc에서 메소드는 일반적으로 클래스의 인스턴스가 아닌 모든 멤버 / 메소드에 암시 적으로 액세스 할 수 있으므로이 구별이 Python / Ruby / etc와 같은 언어에만 존재하는 이유 일 수 있습니다.


C / C ++의 정적 메소드에는 클래스 오브젝트에 대한 참조가 있습니까? 아니면 수업의 "회원"입니까? 그들은 수업의 새로운 회원을 만들 수 있습니까? :)
Aaron Hall

3
@AaronHall C / C ++에는 클래스 객체와 같은 것이 없으며 정적 메서드를 호출하기 위해 이에 대한 참조가 필요하지 않습니다. 당신은 단지 글을 쓰고 Class::staticMethod()그것입니다 ( staticMethod()비공개 적이 거나 무언가 이기 때문에 그것을 호출하는 것을 금지하지 않는 한 ).
Ixrec
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.