2012-06-24 2 views
1

나는 사용자 입력을 기반으로 구성 파일을 생성하는 매우 간단한 응용 프로그램을 작성했습니다. 그러나 StringIO에서 실제 conf 파일로 데이터가 덤프되는 순서는 파일을 사용하는 프로그램에 중요합니다. 내 코드에서이 문제를 해결 한 방법은 위에서 아래로의 데이터 입력 모델이었습니다. 그러나 사용자가 순서에 맞지 않는 데이터를 입력하면 프로그램이 실패하거나 결과 파일이 쓸모 없게됩니다. 임의의 데이터 입력 순서를 재조정하고 StringIO의 데이터가 특정 순서로 삽입되는지 확인하는 방법이 있습니까? 데이터가 StringIO에 입력되는 순서를 어떻게 만드나요? - Python

는 현재 코드는 다음과 같습니다 (그리고 너희들의 도움이 많은이 단계에 도착!) 당신은 출력 생성에서 데이터 수집을 분리 할 필요가

 self.output = StringIO.StringIO()  

    context = self.toolbar.get_style_context() 
    context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR) 



def on_servername_activate(self, widget): 
    output = StringIO.StringIO()   
    servername = widget.get_text() 
    self.output.write("USHARE_NAME="+servername+'\n') 

def on_netif_changed(self, widget): 
    netif = widget.get_active_text() 
    self.output.write("USHARE_IFACE="+netif+'\n') 

def on_port_activate(self, widget): 
    port = widget.get_text() 
    self.output.write("USHARE_PORT="+port+'\n') 

def on_telprt_activate(self, widget): 
    telprt = widget.get_text() 
    self.output.write("USHARE_TELNET_PORT="+telprt+'\n') 

def on_dirs_activate(self, widget): 
    dirs = widget.get_text() 
    self.output.write("USHARE_DIR="+dirs+'\n') 

def on_iconv_toggled(self, widget): 
    iconv = widget.get_active() 
    if iconv == True: 
     self.output.write("USHARE_OVERRIDE_ICONV_ERR="+"True"+'\n') 
    else: 
     self.output.write("USHARE_OVERRIDE_ICONV_ERR="+"False"+'\n') 

def on_webif_toggled(self, widget): 
    webif = widget.get_active() 
    if webif == True: 
     self.output.write("USHARE_ENABLE_WEB="+"yes"+'\n') 
    else: 
     self.output.write("USHARE_ENABLE_WEB="+"no"+'\n') 

def on_telif_toggled(self, widget): 
    telif = widget.get_active() 
    if telif == True: 
     self.output.write("USHARE_ENABLE_TELNET="+"yes"+'\n') 
    else: 
     self.output.write("USHARE_ENABLE_TELNET="+"no"+'\n') 

def on_xbox_toggled(self, widget): 
    xbox = widget.get_active() 
    if xbox == True: 
     self.output.write("USHARE_ENABLE_XBOX="+"yes"+'\n') 
    else: 
     self.output.write("USHARE_ENABLE_XBOX="+"no"+'\n') 

def on_dlna_toggled(self, widget): 
    dlna = widget.get_active() 
    if dlna == True: 
     self.output.write("USHARE_ENABLE_DLNA="+"yes"+'\n') 
    else: 
     self.output.write("USHARE_ENABLE_DLNA="+"no"+'\n') 

def on_commit_clicked(self, widget): 
    commit = self.output.getvalue() 
    logfile = open('/home/boywithaxe/Desktop/ushare.conf','w') 
    logfile.write(commit) 

def on_endprogram_clicked(self, widget): 
    sys.exit(0) 
+0

왜 코드를 읽는 코드를 수정할 수 없습니까? –

답변

3
은 t 그래서 코드를 다시 작성

필드가 변경 될 때마다 config 파일 문자열을 쓰는 대신에, 메모리에있는 dictionary의 값을 변경하려고합니다. 그런 다음 on_commit_clicked 함수에서 해당 사전을 사용하여 필요에 따라 구성 파일 문자열을 정확하게 빌드하십시오.

+0

제 독창적 인 아이디어를 확인해 주셔서 감사드립니다. – boywithaxe

1

. 예를 들어 telnet_port, ushare_iface, ushare_dir 속성을 가진 별도의 ConfigBuilder 클래스와 생성 된 문자열 blob 만 반환하는 메서드를 상상해보십시오. 사용자가 커밋 버튼을 클릭 할 때

def on_servername_activate(self, widget): 
    servername = widget.get_text() 
    self.builder.ushare_name = servername 

하고, 당신은 설정을 생성하고 파일에 쓰기 :

def on_commit_clicked(self, widget): 
    logfile = open('/home/boywithaxe/Desktop/ushare.conf','w') 
    logfile.write(self.builder.build()) 

당신이 돈이 '그런 다음 방법은 바로 builder의 필드를 설정합니다 t는 별도의 빌더 클래스를 갖고 싶어, 당신은 사전에 입력 데이터를 수집 또는 당신의 창 클래스의 멤버 필드와 멀리 얻을 수 있습니다 :

class MyApp(...): 

    ushare_name = None 
    ... more fields to store user input 

    def can_build(self): 
     if self.ushare_name and 
      self.ushare_xxx and 
      self.ushare_yyy and 
      self.phase_of_moon_is_right(): 
      return True 
     return False 

    def build_config(self): 
     return "BLAH =" + self.ushare_name + ... 

    def on_servername_activate(self, widget): 
     servername = widget.get_text() 
     self.ushare_name = servername 

    def on_commit_clicked(self, widget): 
     if self.can_build(): 
      logfile = open('/home/boywithaxe/Desktop/ushare.conf','w') 
      logfile.write(self.build_config()) 
     else: 
      display_some_warning_message("Data incomplete, the commit button should've been hidden/disabled so the user can't click until the app has all data it needs") 
+0

나는 사전 생각이 더 좋다고 생각한다. 나는 초기 단계에서 그것을 고려해 보았지만 그 아이디어는 무시했다. 나는 내일 그 첫 번째 일에 착수하여 결과를 알려줄 것입니다. – boywithaxe

+1

글쎄, 나는 별도의'ConfigBuilder'가 UI를 로직과 분리하는 관점에서 보면 더 깨끗한 해결책이 될 것이라고 생각한다. 그러나 이것은 (거의) 순수하게 미적인 차이점이다. dict도 괜찮을 것입니다. – Sergey

+0

나는 약간의 실험을했고 두 개의 서로 다른 버전의 코드에서 사전뿐만 아니라'ConfigBuilder'를 만들었지 만, 런타임에는 TypeError를 얻습니다. 구체적으로'TypeError : + : 'NoneType'과 'str''에 대해 지원되지 않는 피연산자 유형입니다.'self.ushare_xxxxxx '에 할당 된 데이터가 실제로'str'입니다. 나는 호기심을 묻지 만 왜 그 유형이 잘못 되었습니까? – boywithaxe

1

필요한 각 기능을 장식하십시오 (위젯을 사용하고 블리츠가 'on_ *'방법을 사용하는 적합한 데코레이터 또는 잠재적으로 클래스 데코레이터를 반환하는 간단한 메소드) - 반복 횟수가 많고 데코레이터를 추가해야합니다. 목록이나 뭐.

def on_webif_toggled(self, widget): 
    webif = widget.get_active() 
    if webif == True: 
     self.output.write("USHARE_ENABLE_WEB="+"yes"+'\n') 
    else: 
     self.output.write("USHARE_ENABLE_WEB="+"no"+'\n') 

내가 == True가 제대로 is True로 작성해야하거나 if webif: 하나 구해 신원 확인이 평등 검사보다 더 효율적 있음을 알아 두셔야합니다.

+0

이 발언을 주셔서 감사 드리며, 또한 코드를 읽기 쉽게 만듭니다. – boywithaxe

관련 문제