코드와 함께 파이썬에서 바인딩되지 않은 메서드 오류가 발생했습니다.
import random
class Sample(object):
'''This class defines various methods related to the sample'''
def drawSample(samplesize,List):
sample=random.sample(List,samplesize)
return sample
Choices=range(100)
print Sample.drawSample(5,Choices)
여기에서 많은 유용한 게시물을 읽은 후 @staticmethod
코드를 작동시키기 위해 위에 추가 할 수있는 방법을 찾았습니다 . 저는 파이썬 초보자입니다. 누군가 정적 메서드를 정의하려는 이유를 설명해 주시겠습니까? 아니면 왜 모든 메서드가 정적 메서드로 정의되지 않았습니까?
답변
정적 메서드는 클래스의 인스턴스 속성에 액세스 할 수없고 (일반 메서드와 마찬가지로) 클래스 자체의 속성에 액세스 할 수 없기 때문에 사용이 제한됩니다. ).
따라서 일상적인 방법에는 유용하지 않습니다.
그러나 이들은 제공된 매개 변수 (및 모듈에 전역 적으로 일부 속성)와는 별도로 정보에 액세스 할 필요가없는 클래스 (예 : 한 유형에서 다른 유형으로의 간단한 변환)와 함께 일부 유틸리티 함수를 그룹화하는 데 유용 할 수 있습니다. )
클래스 외부에 둘 수 있지만 클래스 내부에 그룹화하면 해당 위치에서만 적용 할 수 있습니다.
또한 모듈 이름이 아닌 인스턴스 또는 클래스를 통해 메서드를 참조 할 수도 있습니다. 이렇게하면 독자가 메서드가 관련된 인스턴스를 이해하는 데 도움이 될 수 있습니다.
답변
자세한 설명 은 이 기사 를 참조하십시오 .
TL; DR
1. self
논쟁 의 사용을 제거합니다 .
2. Python은 시작된 각 개체에 대해 바인딩 된 메서드 를 인스턴스화 할 필요가 없기 때문에 메모리 사용량을 줄입니다 .
>>>RandomClass().regular_method is RandomClass().regular_method
False
>>>RandomClass().static_method is RandomClass().static_method
True
>>>RandomClass.static_method is RandomClass().static_method
True
3. 코드 가독성을 향상시켜 메서드가 객체 자체의 상태에 의존하지 않음을 나타냅니다.
4. 메서드가 모듈 수준 (즉, 클래스 외부)에서 정의 된 경우 하위 클래스가 해당 메서드를 재정의 할 수 없다는 점에서 메서드 재정의를 허용합니다.
답변
이것은 실제 질문의 요점은 아니지만 당신이 파이썬 초보자라고 말했기 때문에 아마도 도움이 될 것이며 다른 누구도 분명히 나와서 명시 적으로 말하지 않았습니다.
메서드를 정적 메서드로 만들어 위의 코드를 수정하지 않았을 것입니다. 클래스를 버리고 함수를 작성했을 것입니다.
def drawSample(samplesize,List):
sample=random.sample(List,samplesize)
return sample
Choices=range(100)
print drawSample(5,Choices)
관련 함수가 많으면 모듈로 그룹화 할 수 있습니다. 즉, sample.py
예를 들어 이름이 같은 파일에 모두 넣습니다 . 그때
import sample
Choices=range(100)
print sample.drawSample(5,Choices)
또는 __init__
클래스에 메서드를 추가하고 유용한 메서드가있는 인스턴스를 만들었습니다.
class Sample(object):
'''This class defines various methods related to the sample'''
def __init__(self, thelist):
self.list = thelist
def draw_sample(self, samplesize):
sample=random.sample(self.list,samplesize)
return sample
choices=Sample(range(100))
print choices.draw_sample(5)
(또한 PEP 8에서 권장하는 스타일과 일치하도록 위의 예에서 대소 문자 규칙을 변경했습니다.)
파이썬의 장점 중 하나는 모든 것에 클래스를 사용하도록 강요하지 않는다는 것입니다. 클래스의 용도 인 메서드와 연결되어야하는 데이터 또는 상태가있는 경우에만 사용할 수 있습니다. 그렇지 않으면 기능을 사용할 수 있습니다.
답변
정적 메서드를 정의하려는 이유는 무엇 입니까?
우리가이 있다고 가정 class
이라는 Math
다음
아무도의 객체를 생성 할 것 class Math
같은 방법 다음 호출 ceil
하고 floor
그리고 fabs
거기에있다.
그래서 우리는 그들을 만듭니다 static
.
예를 들어
>> Math.floor(3.14)
보다 훨씬 낫다
>> mymath = Math()
>> mymath.floor(3.14)
그래서 그들은 어떤면에서 유용합니다. 이를 사용하기 위해 클래스의 인스턴스를 만들 필요는 없습니다.
모든 메서드가 정적 메서드로 정의되지 않는 이유는 무엇 입니까?
인스턴스 변수에 액세스 할 수 없습니다.
class Foo(object):
def __init__(self):
self.bar = 'bar'
def too(self):
print self.bar
@staticmethod
def foo():
print self.bar
Foo().too() # works
Foo.foo() # doesn't work
그렇기 때문에 모든 메서드를 정적으로 만들지 않습니다.
답변
객체 인스턴스에서 함수 객체를 호출하면 ‘바운드 메서드’가되고 인스턴스 객체 자체가 첫 번째 인수로 전달됩니다.
classmethod
객체 인스턴스에서 객체 (함수 객체를 래핑) 를 호출 하면 인스턴스 객체의 클래스가 첫 번째 인수로 전달됩니다.
staticmethod
객체 (함수 객체를 래핑) 를 호출 할 때 암시 적 첫 번째 인수가 사용되지 않습니다.
class Foo(object):
def bar(*args):
print args
@classmethod
def baaz(*args):
print args
@staticmethod
def quux(*args):
print args
>>> foo = Foo()
>>> Foo.bar(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got int instance instead)
>>> Foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> Foo.quux(1,2,3)
(1, 2, 3)
>>> foo.bar(1,2,3)
(<Foo object at 0x1004a4510>, 1, 2, 3)
>>> foo.baaz(1,2,3)
(<class 'Foo'>, 1, 2, 3)
>>> foo.quux(1,2,3)
(1, 2, 3)
답변
정적 메서드는 메서드가 속한 개체의 인스턴스를 선언 할 필요가 없기 때문에 훌륭합니다.
파이썬 사이트에는 정적 메서드에 대한 몇 가지 훌륭한 문서가 있습니다.
http://docs.python.org/library/functions.html#staticmethod
답변
A와 대안은 staticmethod
:입니다 classmethod
, instancemethod
하고 function
. 이것이 무엇인지 모르는 경우 마지막 섹션으로 스크롤하십시오. a staticmethod
가 이러한 대안 중 어느 것보다 낫다면 작성 목적에 따라 다릅니다.
Python 정적 메서드의 장점
- 클래스 나 인스턴스의 속성이나 메서드에 액세스 할 필요가없는
staticmethod
경우 a가classmethod
또는instancemethod
. 그렇게하면 (@staticmethod
데코레이터에서) 클래스와 인스턴스의 상태가 읽히거나 수정되지 않는다는 것이 분명해집니다 . 그러나 a를function
사용하면 구분이 더욱 명확 해집니다 (단점 참조). - a의 호출 서명은
staticmethod
aclassmethod
또는instancemethod
, 즉<instance>.<method>(<arguments>)
. 따라서 나중에 필요할 경우 또는 파생 클래스에서 세 가지 중 하나로 쉽게 대체 할 수 있습니다 . 간단한function
. - A
staticmethod
대신 A 를 사용function
하여 주관적으로 클래스에 속함을 확인하고 네임 스페이스 충돌을 방지 할 수 있습니다.
파이썬 정적 메서드의 단점
- 인스턴스 또는 클래스의 속성이나 메서드에 액세스 할 수 없습니다.
- a의 호출 서명
staticmethod
은 aclassmethod
또는 의 호출 서명과 동일instancemethod
합니다. 이것은staticmethod
실제로 객체 정보를 읽거나 수정하지 않는다는 사실을 숨 깁니다 . 이것은 코드를 읽기 어렵게 만듭니다. 왜 사용하지function
않습니까? - A
staticmethod
는 정의 된 클래스 / 인스턴스 외부에서 호출해야하는 경우 재사용하기 어렵습니다. 재사용 가능성이있는 경우 afunction
가 더 나은 선택입니다. - 는
staticmethod
사람들이 하나 읽어 약간의 시간이 소요될 수 있습니다 포함 코드를 읽기 때문에 거의 사용되지 않는다.
Python의 정적 메서드에 대한 대안
의 장점에 대해 논의하려면 staticmethod
대안이 무엇이며 서로 어떻게 다른지 알아야합니다.
- 은
staticmethod
클래스에 속하지만 인스턴스 또는 클래스 정보에 액세스하거나 수정할 수 없습니다.
이에 대한 세 가지 대안이 있습니다.
- 는
classmethod
호출 측의 클래스에 액세스 할 수 있습니다. - 는
instancemethod
발신자의 인스턴스와 해당 클래스에 액세스 할 수 있습니다. - 은
function
수업과는 아무 상관이 없습니다. 기능이staticmethod
.
코드에서 다음과 같이 표시됩니다.
# function
# has nothing to do with a class
def make_cat_noise(asker_name):
print('Hi %s, mieets mieets!' % asker_name)
# Yey, we can make cat noises before we've even defined what a cat is!
make_cat_noise('JOey') # just a function
class Cat:
number_of_legs = 4
# special instance method __init__
def __init__(self, name):
self.name = name
# instancemethod
# the instance (e.g. Cat('Kitty')) is passed as the first method argument
def tell_me_about_this_animal(self, asker_name):
print('Hi %s, This cat has %d legs and is called %s'
% (asker_name, self.number_of_legs, self.name))
# classmethod
# the class (e.g. Cat) is passed as the first method argument
# by convention we call that argument cls
@classmethod
def tell_me_about_cats(cls, asker_name):
print("Hi %s, cats have %d legs."
% (asker_name, cls.number_of_legs))
# cls.name # AttributeError because only the instance has .name
# self.name # NameError because self isn't defined in this namespace
# staticmethod
# no information about the class or the instance is passed to the method
@staticmethod
def make_noise(asker_name):
print('Hi %s, meooow!' % asker_name)
# class and instance are not accessible from here
# one more time for fun!
make_cat_noise('JOey') # just a function
# We just need the class to call a classmethod or staticmethod:
Cat.make_noise('JOey') # staticmethod
Cat.tell_me_about_cats('JOey') # classmethod
# Cat.tell_me_about_this_animal('JOey') # instancemethod -> TypeError
# With an instance we can use instancemethod, classmethod or staticmethod
mycat = Cat('Kitty') # mycat is an instance of the class Cat
mycat.make_noise('JOey') # staticmethod
mycat.tell_me_about_cats('JOey') # classmethod
mycat.tell_me_about_this_animal('JOey') # instancemethod