다음과 같이 클래스를 초기화하지 않고 호출할 수 있는 정적 메서드를 Python에서 가질 수 있습니까?
ClassName.static_method()
질문자 :Joan Venge
다음과 같이 클래스를 초기화하지 않고 호출할 수 있는 정적 메서드를 Python에서 가질 수 있습니까?
ClassName.static_method()
예, staticmethod 데코레이터를 사용하여
class MyClass(object): @staticmethod def the_static_method(x): print(x) MyClass.the_static_method(2) # outputs 2
일부 코드는 데코레이터가 아닌 함수로 staticmethod
를 사용하여 정적 메서드를 정의하는 이전 메서드를 사용할 수 있습니다. 이것은 고대 버전의 Python(2.2 및 2.3)을 지원해야 하는 경우에만 사용해야 합니다.
class MyClass(object): def the_static_method(x): print(x) the_static_method = staticmethod(the_static_method) MyClass.the_static_method(2) # outputs 2
이것은 멋진 데코레이터 구문을 사용하지 않는다는 점을 @staticmethod
하고 첫 번째 예제( @staticmethod 사용)와 완전히 동일합니다.
마지막으로 staticmethod
드물게 사용하십시오! Python에서 정적 메서드가 필요한 상황은 거의 없으며 별도의 "최상위" 기능이 더 명확했을 때 정적 메서드가 사용되는 것을 여러 번 보았습니다.
정적 메서드는 암시적 첫 번째 인수를 받지 않습니다. 정적 메서드를 선언하려면 다음 관용구를 사용합니다.
class C: @staticmethod def f(arg1, arg2, ...): ...
@staticmethod 형태는 함수 인 장식 - 함수의 정의에 대한 설명을 참조 함수 정의 자세한.
Cf()
) 또는 인스턴스(예:C().f()
)에서 호출할 수 있습니다. 해당 클래스를 제외하고 인스턴스는 무시됩니다.Python의 정적 메소드는 Java 또는 C++에서 볼 수 있는 것과 유사합니다. 고급 개념은
classmethod()
참조하십시오.정적 방법에 대한 자세한 내용은의 표준 유형 계층에 대한 문서 참조 표준 유형 계층 구조를 .
버전 2.2의 새로운 기능.
버전 2.4에서 변경: 함수 데코레이터 구문이 추가되었습니다.
나는 스티븐이 실제로 옳다고 생각한다. 원래 질문에 답하려면 클래스 메서드를 설정하기 위해 첫 번째 인수가 호출 인스턴스가 되지 않을 것이라고 가정하고 클래스에서 메서드만 호출하도록 합니다.
(이 답변은 Python 3.x를 나타냅니다. Python 2.x에서는 클래스 자체에서 메서드를 호출할 TypeError
예를 들어:
class Dog: count = 0 # this is a class variable dogs = [] # this is a class variable def __init__(self, name): self.name = name #self.name is an instance variable Dog.count += 1 Dog.dogs.append(name) def bark(self, n): # this is an instance method print("{} says: {}".format(self.name, "woof! " * n)) def rollCall(n): #this is implicitly a class method (see comments below) print("There are {} dogs.".format(Dog.count)) if n >= len(Dog.dogs) or n < 0: print("They are:") for dog in Dog.dogs: print(" {}".format(dog)) else: print("The dog indexed at {} is {}.".format(n, Dog.dogs[n])) fido = Dog("Fido") fido.bark(3) Dog.rollCall(-1) rex = Dog("Rex") Dog.rollCall(0)
이 코드에서 "rollCall" 메서드는 첫 번째 인수가 인스턴스가 아니라고 가정합니다(클래스 대신 인스턴스에 의해 호출된 경우처럼). "rollCall"이 인스턴스가 아닌 클래스에서 호출되는 한 코드는 제대로 작동합니다. 인스턴스에서 "rollCall"을 호출하려고 하면 다음과 같이 됩니다.
rex.rollCall(-1)
그러나 두 개의 인수(자체 및 -1)를 보내고 "rollCall"은 하나의 인수만 허용하도록 정의되어 있기 때문에 예외가 발생합니다.
덧붙여서, rex.rollCall()은 올바른 수의 인수를 보내지만 함수가 n이 숫자일 것으로 예상할 때 이제 n이 Dog 인스턴스(즉, rex)를 나타내기 때문에 예외가 발생하기도 합니다.
여기에서 장식이 시작됩니다. "rollCall" 메서드 앞에
@staticmethod
그런 다음 메서드가 정적임을 명시적으로 명시하여 인스턴스에서 호출할 수도 있습니다. 지금,
rex.rollCall(-1)
작동 할 것이다. 메서드 정의 전에 @staticmethod를 삽입하면 인스턴스가 자신을 인수로 보내는 것을 중지합니다.
@staticmethod 행을 주석 처리하거나 주석 처리하지 않고 다음 코드를 시도하여 이를 확인할 수 있습니다.
class Dog: count = 0 # this is a class variable dogs = [] # this is a class variable def __init__(self, name): self.name = name #self.name is an instance variable Dog.count += 1 Dog.dogs.append(name) def bark(self, n): # this is an instance method print("{} says: {}".format(self.name, "woof! " * n)) @staticmethod def rollCall(n): print("There are {} dogs.".format(Dog.count)) if n >= len(Dog.dogs) or n < 0: print("They are:") for dog in Dog.dogs: print(" {}".format(dog)) else: print("The dog indexed at {} is {}.".format(n, Dog.dogs[n])) fido = Dog("Fido") fido.bark(3) Dog.rollCall(-1) rex = Dog("Rex") Dog.rollCall(0) rex.rollCall(-1)
예, staticmethod 데코레이터를 확인하십시오.
>>> class C: ... @staticmethod ... def hello(): ... print "Hello World" ... >>> C.hello() Hello World
@staticmethod
데코레이터를 사용할 필요가 없습니다. (self 매개변수를 기대하지 않는) 메소드를 선언하고 클래스에서 호출하기만 하면 됩니다. 데코레이터는 인스턴스에서도 호출할 수 있기를 원하는 경우에만 존재합니다(원한 것이 아님)
대부분 기능만 사용하지만...
Python의 정적 메서드?
다음과 같이 클래스를 초기화하지 않고 호출할 수 있도록 Python에서 정적 메서드를 가질 수 있습니까?
ClassName.StaticMethod()
예, 정적 메서드는 다음과 같이 만들 수 있습니다(메소드에 CamelCase 대신 밑줄을 사용 하는 것이 조금 더 Pythonic하지만).
class ClassName(object): @staticmethod def static_method(kwarg1=None): '''return a value that is a function of kwarg1'''
위는 데코레이터 구문을 사용합니다. 이 구문은 다음과 같습니다.
class ClassName(object): def static_method(kwarg1=None): '''return a value that is a function of kwarg1''' static_method = staticmethod(static_method)
이것은 당신이 설명한 대로 사용할 수 있습니다:
ClassName.static_method()
정적 메서드의 내장 예제는 Python 3의 str.maketrans()
이며, 이는 Python 2 string
설명할 때 사용할 수 있는 또 다른 옵션은 classmethod
. 차이점은 classmethod가 클래스를 암시적 첫 번째 인수로 가져오고 하위 클래스화된 경우 하위 클래스를 암시적 첫 번째 인수로 가져옵니다.
class ClassName(object): @classmethod def class_method(cls, kwarg1=None): '''return a value that is a function of the class and kwarg1'''
cls
는 첫 번째 인수의 필수 이름이 아니지만 대부분의 경험 많은 Python 코더는 다른 것을 사용하는 경우 잘못된 이름으로 간주할 것입니다.
이들은 일반적으로 대체 생성자로 사용됩니다.
new_instance = ClassName.class_method()
내장 예제는 dict.fromkeys()
.
new_dict = dict.fromkeys(['key1', 'key2'])
정적 메서드 개체가 작동하는 방식의 특수성을 제외하고는 모듈 수준 코드를 구성할 때 이러한 개체로 눈에 띄는 특정 종류의 아름다움이 있습니다.
# garden.py def trim(a): pass def strip(a): pass def bunch(a, b): pass def _foo(foo): pass class powertools(object): """ Provides much regarded gardening power tools. """ @staticmethod def answer_to_the_ultimate_question_of_life_the_universe_and_everything(): return 42 @staticmethod def random(): return 13 @staticmethod def promise(): return True def _bar(baz, quux): pass class _Dice(object): pass class _6d(_Dice): pass class _12d(_Dice): pass class _Smarter: pass class _MagicalPonies: pass class _Samurai: pass class Foo(_6d, _Samurai): pass class Bar(_12d, _Smarter, _MagicalPonies): pass
...
# tests.py import unittest import garden class GardenTests(unittest.TestCase): pass class PowertoolsTests(unittest.TestCase): pass class FooTests(unittest.TestCase): pass class BarTests(unittest.TestCase): pass
...
# interactive.py from garden import trim, bunch, Foo f = trim(Foo()) bunch(f, Foo())
...
# my_garden.py import garden from garden import powertools class _Cowboy(garden._Samurai): def hit(): return powertools.promise() and powertools.random() or 0 class Foo(_Cowboy, garden.Foo): pass
이제 특정 구성 요소가 사용되어야 하는 컨텍스트에서 좀 더 직관적이고 자체 문서화되며 고유한 테스트 케이스의 이름을 지정하는 데 이상적일 뿐만 아니라 테스트 모듈이 순수주의자를 위한 테스트 중인 실제 모듈에 매핑되는 방법에 대한 직접적인 접근 방식을 갖습니다. .
프로젝트의 유틸리티 코드를 구성하는 데 이 접근 방식을 적용하는 것이 실행 가능한 경우가 종종 있습니다. 꽤 자주, 사람들은 즉시 utils
패키지를 만들고 결국 9개의 모듈로 끝납니다. 그 중 하나에는 120 LOC가 있고 나머지는 기껏해야 24개 LOC입니다. 나는 이것으로 시작하여 패키지로 변환하고 진정으로 가치가 있는 짐승만을 위한 모듈을 만드는 것을 선호합니다.
# utils.py class socket(object): @staticmethod def check_if_port_available(port): pass @staticmethod def get_free_port(port) pass class image(object): @staticmethod def to_rgb(image): pass @staticmethod def to_cmyk(image): pass
아마도 가장 간단한 옵션은 해당 함수를 클래스 외부에 두는 것입니다.
class Dog(object): def __init__(self, name): self.name = name def bark(self): if self.name == "Doggy": return barking_sound() else: return "yip yip" def barking_sound(): return "woof woof"
이 방법을 사용하면 내부 객체 상태를 수정하거나 사용하는(부작용이 있는) 함수를 클래스에 보관할 수 있고 재사용 가능한 유틸리티 함수를 외부로 이동할 수 있습니다.
이 파일의 이름이 dogs.py
. 이것들을 사용하려면 전화 것 dogs.barking_sound()
대신 dogs.Dog.barking_sound
.
클래스의 일부로 정적 메서드가 정말로 필요한 경우 staticmethod 데코레이터를 사용할 수 있습니다.
따라서 정적 메서드는 클래스의 개체를 만들지 않고 호출할 수 있는 메서드입니다. 예를 들어 :-
@staticmethod def add(a, b): return a + b b = A.add(12,12) print b
위의 예제에서 add
메소드는 객체 이름이 아닌 클래스 이름 A
나는 때때로 이 질문을 만난다. 내가 좋아하는 사용 사례와 예는 다음과 같습니다.
jeffs@jeffs-desktop:/home/jeffs $ python36 Python 3.6.1 (default, Sep 7 2017, 16:36:03) [GCC 6.3.0 20170406] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cmath >>> print(cmath.sqrt(-4)) 2j >>> >>> dir(cmath) ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'inf', 'infj', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'nan', 'nanj', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau'] >>>
cmath 객체에는 상태가 없기 때문에 cmath 클래스의 객체를 생성하는 것은 의미가 없습니다. 그러나 cmath는 모두 어떤 방식으로든 관련된 메서드 모음입니다. 위의 예에서 cmath의 모든 함수는 어떤 식으로든 복소수에 작용합니다.
Python 정적 메서드는 두 가지 방법으로 만들 수 있습니다.
정적 메서드() 사용
class Arithmetic: def add(x, y): return x + y # create add static method Arithmetic.add = staticmethod(Arithmetic.add) print('Result:', Arithmetic.add(15, 10))
산출:
결과: 25
@static 메소드 사용
class Arithmetic: # create add static method @staticmethod def add(x, y): return x + y print('Result:', Arithmetic.add(15, 10))
산출:
결과: 25
출처 : http:www.stackoverflow.com/questions/735975/static-methods-in-python
Git 병합 대신 Git 리베이스를 언제 사용합니까? (0) | 2021.12.31 |
---|---|
인덱스로 목록에서 요소를 제거하는 방법 (0) | 2021.12.31 |
꼬리 재귀 란 무엇입니까? (0) | 2021.12.31 |
SQL Server의 LEFT JOIN 대 LEFT OUTER JOIN (0) | 2021.12.31 |
추적되지 않은 파일을 어떻게 숨기나요? (0) | 2021.12.31 |