함수 장식의 차이 무엇 @staticmethod
하나는 장식은 @classmethod
?
답변
의 호출 서명에 공지 사항을 차이를 : 어쩌면 예제 코드의 약간의 도움이 될 것입니다 foo
, class_foo
그리고 static_foo
:
class A(object):
def foo(self, x):
print "executing foo(%s, %s)" % (self, x)
@classmethod
def class_foo(cls, x):
print "executing class_foo(%s, %s)" % (cls, x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)" % x
a = A()
다음은 객체 인스턴스가 메소드를 호출하는 일반적인 방법입니다. 객체 인스턴스 a
는 암시 적으로 첫 번째 인수로 전달됩니다.
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)
classmethods를 사용하면 객체 인스턴스의 클래스가 암시 적으로 대신 첫 번째 인수로 전달됩니다 self
.
a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
class_foo
수업을 사용하여 전화 할 수도 있습니다 . 실제로 무언가를 클래스 메소드로 정의하면 클래스 인스턴스가 아닌 클래스에서 호출하려고하기 때문일 수 있습니다. A.foo(1)
TypeError가 발생했지만 A.class_foo(1)
정상적으로 작동합니다.
A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
사람들이 클래스 메소드를 찾은 한 가지 용도는 상속 가능한 대체 생성자 를 만드는 것 입니다.
staticmethods으로 , 둘 다 self
(객체 인스턴스)도 cls
(클래스)을 암시 적으로 첫 번째 인수로 전달되지 않습니다. 인스턴스 또는 클래스에서 호출 할 수 있다는 점을 제외하고는 일반 함수처럼 작동합니다.
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
정적 메소드는 클래스와 클래스와 논리적으로 연결된 함수를 그룹화하는 데 사용됩니다.
foo
는 함수일 뿐이지 만 함수를 호출 a.foo
할 때 함수 a
의 첫 번째 인수로 개체 인스턴스가 바인딩 된 함수의 “부분적으로 적용되는”버전의 함수를 얻습니다 . foo
인수는 2 개, 인수 a.foo
는 1 개만 필요합니다.
a
에 바인딩되어 foo
있습니다. 이것이 아래 “바운드”라는 용어의 의미입니다.
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
와 a.class_foo
, a
결합되지 class_foo
않고 클래스가, A
바인딩됩니다 class_foo
.
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
정적 메소드를 사용하는 경우 여기에서는 메소드이지만 a.static_foo
인수가 바인딩되지 않은 우수한 ‘ole 함수를 반환합니다. static_foo
1 개의 인수를
a.static_foo
기대하고 1 개의 인수도 기대합니다.
print(a.static_foo)
# <function static_foo at 0xb7d479cc>
물론 static_foo
클래스 를 호출 할 때도 같은 일이 발생 A
합니다.
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
답변
StaticMethod를가 가에 호출 된 클래스 또는 인스턴스에 대해 아무것도 알고하는 방법입니다. 전달 된 인수를 얻습니다. 암시 적 첫 번째 인수는 없습니다. 파이썬에서는 기본적으로 쓸모가 없습니다. 정적 메소드 대신 모듈 함수를 사용할 수 있습니다.
반면에 classmethod 는 호출 된 클래스 또는 호출 된 인스턴스의 클래스를 첫 번째 인수로 전달하는 메소드입니다. 이것은 메소드가 클래스의 팩토리가되기를 원할 때 유용합니다. 메소드가 첫 번째 인수로 호출 된 실제 클래스를 가져 오므로 서브 클래스가 포함 된 경우에도 항상 올바른 클래스를 인스턴스화 할 수 있습니다. 예를 들어 dict.fromkeys()
classmethod가 서브 클래스에서 호출 될 때 서브 클래스의 인스턴스를 리턴하는 방법을 관찰하십시오 .
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
답변
기본적으로 @classmethod
첫 번째 인수가 (클래스 인스턴스가 아닌) 호출 된 클래스 인 메소드는 @staticmethod
암시 적 인수가 없습니다.
답변
공식 파이썬 문서 :
클래스 메서드는 인스턴스 메서드가 인스턴스를받는 것처럼 클래스를 암시 적 첫 번째 인수로받습니다. 클래스 메소드를 선언하려면 다음 관용구를 사용하십시오.
class C: @classmethod def f(cls, arg1, arg2, ...): ...
@classmethod
형태의 함수이다
장식 – 함수의 정의에 대한 설명을 참조 함수 정의 자세한.클래스 (등
C.f()
) 또는 인스턴스 (등) 에서 호출 할 수 있습니다C().f()
. 클래스를 제외하고 인스턴스는 무시됩니다. 파생 클래스에 대해 클래스 메서드가 호출되면 파생 클래스 개체가 암시 적 첫 번째 인수로 전달됩니다.클래스 메소드는 C ++ 또는 Java 정적 메소드와 다릅니다. 원하는
staticmethod()
경우이 섹션을 참조하십시오 .
정적 메소드는 내재 된 첫 번째 인수를받지 않습니다. 정적 메소드를 선언하려면 다음 관용구를 사용하십시오.
class C: @staticmethod def f(arg1, arg2, ...): ...
@staticmethod
형태의 함수이다
장식 – 함수의 정의에 대한 설명을 참조 함수 정의 자세한.클래스 (등
C.f()
) 또는 인스턴스 (등) 에서 호출 할 수 있습니다C().f()
. 클래스를 제외하고 인스턴스는 무시됩니다.Python의 정적 메소드는 Java 또는 C ++에서 발견되는 메소드와 유사합니다. 고급 개념에 대해서는
classmethod()
이 섹션을 참조하십시오
.
답변
다음은 이 질문에 짧은 기사입니다
@staticmethod 함수는 클래스 안에 정의 된 함수일뿐입니다. 클래스를 먼저 인스턴스화하지 않고 호출 할 수 있습니다. 상속을 통해 정의를 변경할 수 없습니다.
@classmethod 함수는 클래스를 인스턴스화하지 않고도 호출 할 수 있지만 그 정의는 상속을 통해 Parent 클래스가 아닌 Sub 클래스를 따릅니다. @classmethod 함수의 첫 번째 인수는 항상 cls (class) 여야하기 때문입니다.
답변
@staticmethod 또는 @classmethod 사용 여부를 결정하려면 메소드 내부를 살펴 봐야합니다. 메소드가 클래스의 다른 변수 / 메소드에 액세스하는 경우 @classmethod를 사용하십시오 . 반면에, 메소드가 클래스의 다른 부분을 건드리지 않으면 @staticmethod를 사용하십시오.
class Apple:
_counter = 0
@staticmethod
def about_apple():
print('Apple is good for you.')
# note you can still access other member of the class
# but you have to use the class instance
# which is not very nice, because you have repeat yourself
#
# For example:
# @staticmethod
# print('Number of apples have been juiced: %s' % Apple._counter)
#
# @classmethod
# print('Number of apples have been juiced: %s' % cls._counter)
#
# @classmethod is especially useful when you move your function to other class,
# you don't have to rename the class reference
@classmethod
def make_apple_juice(cls, number_of_apples):
print('Make juice:')
for i in range(number_of_apples):
cls._juice_this(i)
@classmethod
def _juice_this(cls, apple):
print('Juicing %d...' % apple)
cls._counter += 1
답변
파이썬에서 @staticmethod와 @classmethod의 차이점은 무엇입니까?
이 의사 코드와 같은 Python 코드를 보았을 것입니다.이 코드는 다양한 메소드 유형의 서명을 보여주고 각각을 설명하는 docstring을 제공합니다.
class Foo(object):
def a_normal_instance_method(self, arg_1, kwarg_2=None):
'''
Return a value that is a function of the instance with its
attributes, and other arguments such as arg_1 and kwarg2
'''
@staticmethod
def a_static_method(arg_0):
'''
Return a value that is a function of arg_0. It does not know the
instance or class it is called from.
'''
@classmethod
def a_class_method(cls, arg1):
'''
Return a value that is a function of the class and other arguments.
respects subclassing, it is called with the class it is called from.
'''
정상적인 인스턴스 방법
먼저 설명하겠습니다 a_normal_instance_method
. 이를 ” 인스턴스 메소드 “라고합니다. 인스턴스 메소드가 사용될 때, 부분 함수 (소스 코드에서 볼 때 모든 값에 대해 정의 된 총 함수와 반대)로 사용됩니다. 즉, 사용될 때 첫 번째 인수는 주어진 속성을 가진 객체. 개체의 인스턴스가 바인딩되어 있으며 개체의 인스턴스에서 호출되어야합니다. 일반적으로 인스턴스의 다양한 속성에 액세스합니다.
예를 들어 다음은 문자열의 인스턴스입니다.
', '
join
이 문자열 에서 인스턴스 메소드를 사용하여 다른 iterable을 결합하는 경우 iterable 목록의 함수 외에도 인스턴스의 함수입니다 ['a', 'b', 'c']
.
>>> ', '.join(['a', 'b', 'c'])
'a, b, c'
바운드 방법
인스턴스 메소드는 나중에 사용하기 위해 점선 조회를 통해 바인딩 될 수 있습니다.
예를 들어, str.join
메소드를 ':'
인스턴스에 바인딩합니다 .
>>> join_with_colons = ':'.join
그리고 나중에 우리는 이미 첫 번째 인수가 바인딩 된 함수로 이것을 사용할 수 있습니다. 이런 식으로 인스턴스에서 부분 함수처럼 작동합니다.
>>> join_with_colons('abcde')
'a:b:c:d:e'
>>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF'])
'FF:FF:FF:FF:FF:FF'
정적 방법
정적 메소드는 인스턴스를 인수로 사용하지 않습니다 .
모듈 수준 기능과 매우 유사합니다.
그러나 모듈 레벨 기능은 모듈에 상주해야하며 모듈이 사용되는 다른 곳으로 특별히 가져와야합니다.
그러나 객체에 첨부 된 경우 가져 오기 및 상속을 통해 편리하게 객체를 따릅니다.
정적 메소드의 예는 str.maketrans
, string
Python 3 의 모듈에서 이동 한 것 str.translate
입니다. 변환 테이블을에서 사용하기에 적합합니다 . 아래에 설명 된 것처럼 문자열 인스턴스에서 사용하면 다소 어리석은 것처럼 보이지만 string
모듈 에서 함수를 가져 오는 것은 다소 어색하고 클래스에서 호출 할 수있는 것이 좋습니다.str.maketrans
# demonstrate same function whether called from instance or not:
>>> ', '.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
>>> str.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
파이썬 2에서는 점점 유용성이 떨어지는 문자열 모듈에서이 함수를 가져와야합니다.
>>> import string
>>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc'))
'abcDEFG'
수업 방법
클래스 메소드는 암시 적 첫 번째 인수를 취한다는 점에서 인스턴스 메소드와 유사하지만 인스턴스를 가져 오는 대신 클래스를 사용합니다. 더 나은 의미 사용을 위해 대체 생성자로 사용되는 경우가 많으며 상속을 지원합니다.
내장 클래스 메소드의 가장 표준적인 예는 dict.fromkeys
입니다. 그것은 dict의 대체 생성자로 사용됩니다 (키가 무엇인지 알고 기본값을 원할 때 적합합니다).
>>> dict.fromkeys(['a', 'b', 'c'])
{'c': None, 'b': None, 'a': None}
dict을 서브 클래스로 만들 때 동일한 생성자를 사용하여 서브 클래스의 인스턴스를 만들 수 있습니다.
>>> class MyDict(dict): 'A dict subclass, use to demo classmethods'
>>> md = MyDict.fromkeys(['a', 'b', 'c'])
>>> md
{'a': None, 'c': None, 'b': None}
>>> type(md)
<class '__main__.MyDict'>
대체 생성자의 다른 유사한 예제 는 pandas 소스 코드 를 참조하십시오 . classmethod
및 공식 Python 문서도 참조하십시오 staticmethod
.