2014-07-10 6 views
0

여러 번 처음 함수를 호출 할 때 간단한 함수를 사용해야 할 필요가있었습니다. 많은 이유가 있지만 일반적으로 처음 실행하면 변수를 다르게 초기화해야합니다. 때로는 함수 나 내부의 문제를 처리 할 수 ​​있지만 때로는 문제가 복잡해질 수 있으며이를 피할 수 있으면 "전역"을 사용하지 않습니다.클래스와 같은 함수 초기화

내 솔루션은 발전기에서 나왔습니다. 프로그램에서 next() 호출을 사용하여 함수의 루프 위에있는 "수율"함수를 사용하여 함수를 "초기화"하거나 함수를 "프라임"할 수 있음을 발견했습니다. 매력처럼 작동합니다.

지금 제 질문은 : 누락 된 수있는 더 나은 방법이 있습니까?

WoNUX - 작동하지만, 비 유용 exammple :

o_PrintList = g_PrintThis() ## Creates func object 
o_PrintList.next() ## 'Primes' the func 
o_PrintList.send(9) ## Sends argument to the func 
o_PrintList.send(10) ## Another argument to the func 

def g_PrintThis(): 
    v_PrintList = [] ## Inits the variable. If stnd func call this would happen everytime 
    print("Initialized") 
    v_Num = yield ## Waits for first send argument 
    while True: ## Infinite loop. Could be a for loop, etc. 
     v_PrintList.append(v_Num) ## Reason v_PrintList needs 'primed' 
     if not v_PrintList: 
      print("PrintList is empty:") 
     else: 
      print("Printlist: %s") %(v_PrintList) 
     v_Num = yield ## Waits for next send argument, if ever one comes 

감사합니다.

+1

http://stackoverflow.com/questions/279561/what-is-the-python-equivalent-of-static-variables-inside-a-function –

+0

명시 적으로 '다음'을 프라임으로 지정하는 경우 그것, 당신은 단지'setup_printing' 함수를 별도로 가지고 처음 설치를 위해 호출 할 수 있습니다. – user2357112

답변

3

하나의 옵션은 실제 클래스를 사용하는 것입니다. 라고 할 때 적절한 동작을 정의 __call__을 구현할 수 있습니다 사용에

class PrintThis(object): 

    def __init__(self, print_list=None): 
     if print_list is None: 
      print_list = [] 
     self.print_list = print_list 

    def __call__(self): 
     if self.print_list: 
      print("Print list: {0}".format(self.print_list)) 
     else: 
      print("Print list empty.") 

    def send(self, item): 
     self.print_list.append(item) 

: 파이썬 기능에서

>>> p = PrintThis() 
>>> p() 
Print list empty. 
>>> p.send(9) 
>>> p.send(10) 
>>> p() 
Print list: [9, 10] 
+0

@jonsharpe 감사합니다. 분명히 클래스가 작동하지만, 간단한 함수의 경우 많은 코드와 복잡한 코드가됩니다. 또한 기능을 "작업"및 클래스를 "엔터티"로 분류하고 사용하는 경향이 있습니다. 나는 할 일들을 보내고 돌아가고, 나는 물건을 보내고 행한다. 간단한 작업을 위해 엔티티를 실제로 만들고 싶습니까? 생각할 거리. –

+0

@Raw_Input 당신의 작업과 엔티티 구별은 파이썬 일반적으로 또는 당신의 예제에 실제로 적용되지 않습니다; 이 경우 작업을 수행하기를 원합니다. – jonrsharpe

1

는 속성을 가질 수있다, 그래서 주어진 속성이 초기화 여부를 판단 할 수 있는지 여부를 테스트 필요합니다

def f(args): 
    if not hasattr(f, "guard"): 
     print "Initializing" 
     f.guard = None 
    print "Called with", args 

f("one") 
f("two") 

인쇄

이것은 글로벌 변수를 사용하지 않아 문제가되는 잠재적 인 문제 (다른 코드가 동일한 전역 변수를 사용하는 경우 관련 질문 하나만 묻는 경우)를 나타냅니다.

+0

함수 본문 내에서 함수에 대한 속성 설정은 기껏해야 취성입니다. 주 (state)가 필요하다면 클래스 (또는 결국 클로저 (closure) ...)를 사용하십시오. –

+0

@holdenweb 고마워. 이것은 내가 자주 얻는 해결책의 한 형태입니다. 그러나 때때로 복잡해질 수 있으며 후속 통화를 중단 할 수도 있습니다. –

+0

설명해주세요.Bruno와는이 솔루션의 취성에 대해 다소 동의하지 않으며 특히 단 하나의 인스턴스 만있을 것이라는 것을 알 수있는 클래스를 선언해야하는 것이 바람직하지 않습니다. – holdenweb

1

함수도 클래스입니다 (정확한 클래스 임). 함수를 호출 할 때 실제로 클래스의 __call__ 메소드를 호출합니다.

jonrsharpe가 말한 것과 마찬가지로, 클래스를 만들고 __init____call__ 메소드를 구현하십시오.

+2

당신이 말한 것의 상당 부분은 정확하지만 함수가 클래스라면 우리는 그 클래스로부터 상속받을 수 있습니다. 함수 유형의 인스턴스입니다. – holdenweb

+0

그리고 당신은 * types.FunctionType'을 상속받을 수 없습니다. – jonrsharpe

+0

예, 비행 중에 functin을 만드는 것은 매우 어렵습니다 (모듈이기 때문에). 그것들은 1 등석 물체일지도 모르지만 실제로는 1 등석 물체가 아닙니다. – holdenweb