2012-03-08 4 views
2

kill 함수에 의해 self.text가 ''로 설정된 경우 'while'은 '중단'되지 않습니다.While 루프 Python 클래스 속성

누군가가이 작업을 수행하거나 더 나은 방법을 제안하도록 도움을 줄 수 있습니까? 문자열이 '' 이되는 경우 종료하는 10 개 이상의 함수를 통해 문자열을 실행해야합니다. 각 함수 내부로 돌아 오는 것이 중복 된 것처럼 보입니다.

class Class(object): 
    def run(self, text): 
     self.text = text 

     while self.text: 
      self.nothing1() 
      self.kill() 
      self.nothing2() 
      return self.text # stop if all functions run 

    def nothing1(self): 
     print 'nothing1' 
     self.text = self.text 

    def kill(self): 
     print 'kill' 
     self.text = '' 

    def nothing2(self): 
     print 'nothing2' 
     self.text = self.text 

C = Class() 
C.run('some string') 

명확한 설명 : 목표는 기능 중 하나가 문자열을 설정하면 한 번만 중지 순서에 많은 기능을 통해 문자열을 실행하는 것입니다 ""로, 나는 분명히, 그것을 어떻게 '동안'작업을 오해 나에게 가장 깨끗한 방법 같아.

+0

이 코드는 실제로 첫 번째 반복을 중단합니다. – Marcin

+0

맞습니다. 왜 누군가가 '살해'에서 깨지지 않는지 명확히 할 수 있습니까? – mark

+3

@mark 왜'kill' 후에 멈추어야합니까? break 문은 없습니다. 따라서 나머지 함수는'kill'을 실행합니다. 그러나 'self.nect == True' 조건이 충족되지 않아'while '의 다음 반복은 실행되지 않습니다. – ovgolovin

답변

0

속성이 ''가되면 StopIteration을 발생시키는 데코레이터를 작성하십시오.

+0

10 개의 각 함수 위에 @decorator가 있습니까? 데코레이터에는 100 %가 아니지만 각 기능에 중복 코드가 포함되지 않도록하는 것이 좋습니다. – mark

+0

그 중 하나 또는 각각의 호출을 데코레이터로 래핑하십시오. 또는 \ _ \ _ getattr \ _ \ _ magic을 할 수도 있지만, 그러지 않으실 것입니다. –

2

당신은 실행 각 함수 뒤에있는 text''의 검사를 추가해야합니다

class Class(object): 
    def run(self, text): 
     self.text = text 

     func_to_exec = [self.nothing1,self.kill,self.nothing2] 
     while True: 
      for func in func_to_exec: 
       func() 
       if not self.text: 
        break 
      else: 
       continue #executed only if no 'break' was met (starts the next iteration of `while` loop) 
      break #get out of the 'while True' loop 


    def nothing1(self): 
     print 'nothing1' 
     self.text = self.text 

    def kill(self): 
     print 'kill' 
     self.text = '' 

    def nothing2(self): 
     print 'nothing2' 
     self.text = self.text 

출력 :

>>> C.run('some string') 
nothing1 
kill 
+0

감사합니다. 멀리까지 깨끗하게하지만, 나는 'while'이 전혀 필요 없다고 생각하지 않는다. 그것은 'for'에서 벗어나야한다. – mark

+1

@mark Hm. 내가 가진 모든 함수는 무한 루프에서 실행 되어야만 그 중 하나가'' '를 반환 할 때까지 실행됩니다. 아니? – ovgolovin

+0

내 잘못, 'return self.text'를 'while'의 하단에 포함하는 것을 잊었습니다. – mark

4

업데이트 2 : 당신의 목표는 여러 가지 기능을 통해 문자열을 실행하는 경우, 당신의 디자인은 본질적으로 모두 잘못되었습니다.

각 함수는 멤버를 설정하지 말고 대신 문자열을 받아 문자열을 반환해야합니다. 루프는 값이 좋은 여부를 테스트해야합니다 :

currstr = 'foo' 
for f in (self.nothing1, self.kill, self.nothing2): 
    tmpstr = f(currstr) 
    if not tmpstr: break # or return, or raise exception 
    currstr = tmpstr 

업데이트 : 분명히 문제가 루프 작업하는 동안 당신이 어떻게 마음에 들지 않는다는 것입니다. while 루프는 실행이 테스트에 도달 할 때만 중단됩니다. 즉, 실행이 본문에 들어가면 중단 또는 예외가 없으면 블록의 끝까지 계속되고 그 후에 만 ​​테스트가 다시 평가됩니다.

아마 가장 깨끗한 방법은 self.textproperty으로 감싸는 것입니다.

그런 다음 귀하의 재산 함수의 논리에 대한 세 가지 합리적인 선택이있다 : 당신은 속성이 변경 될 때 호출되는 핸들러의 시스템을 만들 수 있습니다

  1. 및 (논리 포함 당신이 원하는대로 할 다음 두 가지 옵션 중 하나).
  2. 빈 문자열에 대한 특정 테스트를 포함하고 이에 대한 예외를 발생시키고 루프 외부에서 처리합니다. 또는
  3. 모든 단일 변경에 예외를 발생시키고 루프 내에서 처리하십시오.

위에서 설명한 것과 거의 같은 방법으로 kill에 예외를 발생시키는 또 다른 옵션이 있습니다.


코드는 나를 위해 완벽하게 작동합니다 : 그것은 중복 보일 수도 있지만 각 함수에서 문자열을 반환하는 경우

In [139]: cpaste 
Pasting code; enter '--' alone on the line to stop or use Ctrl-D. 
:class Class(object): 
: def run(self, text): 
:  self.text = text 
: 
:  while self.text: 
:   self.nothing1() 
:   self.kill() 
:   self.nothing2() 
: 
: def nothing1(self): 
:  print 'nothing1' 
:  self.text = self.text 
: 
: def kill(self): 
:  print 'kill' 
:  self.text = '' 
: 
: def nothing2(self): 
:  print 'nothing2' 
:  self.text = self.text 
: 
:C = Class() 
:C.run('some string') 
:-- 
nothing1 
kill 
nothing2 
+0

필자는 모든 함수가'text '를''''로 설정할 수 있습니다. 그러나 나는 틀릴 수도 있습니다. – ovgolovin

+0

아이디어는 죽일 때 멈추고 아무 것도 실행하지 않는 것입니다. – mark

+0

@mark : while 루프가 작동하는 방식이 아닙니다. – Marcin

1

, 당신은 루프를 단축 할 수 있습니다. 게으른 평가를 사용하여 문제에 대한 더 기능적인 접근 방법입니다.

def run(self, text): 
     self.text = text 

     func_to_exec = [self.nothing1, self.kill, self.nothing2] 
     all(func() for func in func_to_exec) # generator will evaluate func lazily 

주석이 깔끔하고 명확합니다.