문제

수업을 선언한다고 말합니다 C 그리고 몇 가지 선언은 매우 유사합니다. 함수를 사용하고 싶습니다 f 이 선언에 대한 코드 반복을 줄입니다. 단지 선언하고 사용하는 것이 가능합니다 f 평소와 같이 :

>>> class C(object):
...     def f(num):
...             return '<' + str(num) + '>'
...     v = f(9)
...     w = f(42)
... 
>>> C.v
'<9>'
>>> C.w
'<42>'
>>> C.f(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method f() must be called with C instance as first argument (got int instance instead)

죄송합니다! 실수로 노출되었습니다 f 외부 세계에, 그러나 그것은 self 논쟁 (그리고 명백한 이유로는 할 수 없습니다). 한 가지 가능성은 del 사용 후 기능 :

>>> class C(object):
...     def f(num):
...             return '<' + str(num) + '>'
...     v = f(9)
...     del f
... 
>>> C.v
'<9>'
>>> C.f
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'C' has no attribute 'f'

그러나 내가 사용하고 싶다면 어떨까요? f 나중에 선언 후? 함수를 삭제하는 것은하지 않습니다. 나는 그것을 "private"로 만들 수 있습니다 (즉, 이름을 접두사로 만듭니다. __) 그리고 그것을 줘 @staticmethod 치료, 그러나 호출 staticmethod 비정상 채널을 통한 물체는 매우 펑키합니다.

>>> class C(object):
...     @staticmethod
...     def __f(num):
...             return '<' + str(num) + '>'
...     v = __f.__get__(1)(9)   # argument to __get__ is ignored...
... 
>>> C.v
'<9>'

위의 미친기 때문에 사용해야합니다 staticmethod 설명자인 물체는 자체적으로 부를 수 없습니다. 랩핑 된 함수를 복구해야합니다 staticmethod 내가 전화하기 전에 물체.

이 작업을 수행하는 더 좋은 방법이 있어야합니다. 클래스에서 함수를 깨끗하게 선언하고 선언 중에 사용하고 나중에 클래스 내에서 사용할 수 있습니까? 내가 이것을해야합니까?

도움이 되었습니까?

해결책

간단히 말해서, 해결책은 f가 클래스의 구성원이 될 필요가 없다는 것입니다. 나는 당신의 생각 프로세스가 정신적 차단을 일으키는 자바 인 언어 필터를 겪었다 고 가정합니다. 그것은 다음과 같이 조금갑니다.

def f(n):
    return '<' + str(num) + '>'

class C(object):

    v = f(9)
    w = f(42)

그런 다음 F를 다시 사용하려면 사용하십시오.

>>> f(4)
'<4>'

이야기의 도덕은 "파이썬에서, 당신은 가지다 모든 것을 수업으로 강요하기 위해 ".

다른 팁

확장 알리 a대답, 모듈 네임 스페이스에서 F를 피하고 싶다면 _f와 같은 수출되지 않은 이름을 사용하거나 __all__를 설정하면 충분하지 않습니다). 그러면 폐쇄 내에서 클래스를 만들어이를 달성 할 수 있습니다.

def create_C():
    def f(num):
        return '<' + str(num) + '>'

    class C(object):
        v = f(9)
        def method_using_f(self, x):  return f(x*2)
    return C

C=create_C()
del create_C

이러한 방식으로 C는 정의와 방법 내에서 F에 액세스 할 수 있지만 다른 방법은 아무것도하지 않습니다 (그 방법에 대한 내성과 관련이 있습니다.C.method_using_f.im_func.func_closure))

그러나 이것은 대부분의 목적에서 과잉 일 것입니다. "_"접두사 이름 지정 규칙을 사용하여 F가 내부임을 문서화하면 일반적으로 충분해야합니다.

편집하다 다른 옵션 중 하나는 사용하려는 메소드에서 사전 랩핑 된 함수 객체에 대한 참조를 유지하는 것입니다. 예를 들어 기본 인수로 설정하여 다음과 같습니다.

class C(object):
    def f(num):
        return '<' + str(num) + '>'

    v = f(9)
    def method_using_f(self, x, f=f):  return f(x*2)

    del f

(폐쇄 접근 방식이 더 좋을 것 같지만)

이것은 하나의 가능성입니다 :

class _C:
    # Do most of the function definitions in here
    @classmethod
    def f(cls):
        return 'boo'

class C(_C):
    # Do the subsequent decoration in here
    v = _C.f()

나는 당신이 이것을하려고한다고 생각합니다.

class C():
...     class F():
...         def __call__(self,num):
...             return "<"+str(num)+">"
...     f=F()
...     v=f(9)
>>> C.v
'<9>'
>>> C.f(25)
'<25>'
>>> 

어쩌면 더 나은 pythonic 솔루션이있을 수 있습니다 ...

"클래스에서 함수를 선언하고 선언 중에 사용하고 나중에 클래스 내에서 사용하십시오."

죄송합니다. 할 수 없습니다.

"할 수 없어"는 파이썬과 어울리지 않는 것 같습니다.

한 가지 옵션 : 더 잘 작성하십시오 staticmethod:

class staticfunc(object):
    def __init__(self, func):
        self.func = func
    def __call__(self, *args, **kw):
        return self.func(*args, **kw)
    def __repr__(self):
        return 'staticfunc(%r)' % self.func

처음부터 시작합시다.

"클래스에서 함수를 선언하고 선언 중에 사용하고 나중에 클래스 내에서 사용하십시오."

죄송합니다. 할 수 없습니다. "선언 중에 사용 된"클래스 ""모순 ".

  • 클래스에서 선언의 일부로 생성 된 수단.
  • 선언 중에 사용되면 클래스 밖에서 존재한다는 것을 의미합니다. 종종 메타 클래스로. 그러나 다른 방법이 있습니다.

CW와 CV가 무엇인지는 확실하지 않습니다. 그들은 단지 끈입니까? 그렇다면 외부 기능 f 최상의 솔루션입니다. "네임 스페이스가 혼란스럽지 않음"은 약간 촉진됩니다. 결국, 당신은 그것을 다시 사용하고 싶습니다.

C와 동일한 모듈에 있습니다. 그래서 Python에는 모듈이 있습니다. 함수와 클래스를 함께 바인딩합니다.

import myCmod

myCmod.C.w
myCmod.C.v
myCmod.f(42)

W와 V가 단순한 문자열이 아니라면 많은 유연성을 제공하는 좋은 솔루션이 있습니다.

일반적으로 이와 같은 클래스 수준 ( "정적") 변수의 경우 다른 클래스를 사용할 수 있습니다. 원하는 API를 완전히 달성하는 것은 불가능하지만 이것은 가깝습니다.

>>> class F(object):
    def __init__( self, num ):
        self.value= num
        self.format= "<%d>" % ( num, )

>>> class C(object):
    w= F(42)
    v= F(9)

>>> C.w
<__main__.F object at 0x00C58C30>
>>> C.w.format
'<42>'
>>> C.v.format
'<9>'

이것의 장점은 F가 확장 될 수있는 적절한 일류라는 것입니다. 우리가 노출을 피하려고하는 "숨겨진"것이 아닙니다. 그것은 인생의 사실이므로, 우리는 공개/폐쇄 된 원칙을 따르고 확장에 개방적으로 만들 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top