2009-10-16 3 views
2

저는 5 개의 모듈에 걸쳐 파이썬으로 중간 크기의 프로그램을 개발 중입니다. 프로그램은 주 모듈에서 OptionParser를 사용하여 명령 줄 인수를 허용합니다. main.py 이 옵션은 나중에 다른 모듈의 메소드가 작동하는 방식을 결정하는 데 사용됩니다 (예 : a.py, b.py). 사용자가 동작이나 프로그램을 사용자 정의 할 수있는 기능을 확장함에 따라 main.py가 직접 호출하지 않고 대신 다른 사용자가 호출하는 a.py의 메소드에서이 사용자 정의 매개 변수가 필요하다는 것을 알게되었습니다 a.py의 방법과도한 매개 변수 전달을 피하는 방법은 무엇입니까?

main.py :

import a 
p = some_command_line_argument_value 
a.meth1(p) 

a.py : 내가 생각할 수 없다 시도로이 과도한 매개 변수 전달이 낭비적이고 잘못된 것 같다,하지만 하드가

meth1(p): 
     # some code 
     res = meth2(p) 
     # some more code w/ res 

meth2(p): 
     # do something with p 

이 문제를 해결하는 디자인 패턴 공식 CS 교육 (B.Sc.에서 CS는 미성년자 임)을 수행하는 동안 파이썬을 사용하기 시작한 이후 좋은 코딩 방법을 고맙게 받아 들였습니다. 더 나은 프로그래머가되도록 도와주세요!

답변

3

아마도 코드를 클래스와 객체로 구성해야할까요? 이 글을 쓰면서 Jimmy는 클래스 기반 인스턴스 응답을 보여 주었기 때문에 순수한 클래스 기반 응답이 있습니다. 이것은 오직 하나의 행동을 원한다면 가장 유용 할 것입니다. 어떤 경우에 다른 기본값이 필요할 수있는 기회가 있다면 Python에서 일반적인 객체 지향 프로그래밍을 사용해야합니다. 즉 클래스가 아닌 인스턴스에 속성 p가 설정된 클래스 인스턴스를 전달해야합니다.

class Aclass(object): 
    p = None 
    @classmethod 
    def init_p(cls, value): 
     p = value 
    @classmethod 
    def meth1(cls): 
     # some code 
     res = cls.meth2() 
     # some more code w/ res 
    @classmethod 
    def meth2(cls): 
     # do something with p 
     pass 

from a import Aclass as ac 

ac.init_p(some_command_line_argument_value) 

ac.meth1() 
ac.meth2() 
+0

"Jimmy"가 대답을 올렸지 만 나는 그곳에서 엉망진창 같다고 생각합니다. 아마도 David Seiler의 대답이었을 것입니다. (나는 심지어 "지미"대답을 여기에서 보지 않는다. ..) 그것에 대해 유감스럽게 생각해 라. – steveha

2

"a"가 독립적 인 도우미 메서드 집합이 아닌 실제 개체 인 경우 "a"에 "p"멤버 변수를 만들고 "a"개체를 인스턴스화 할 때 설정할 수 있습니다. 그런 다음 주 수업은 "a"가 인스턴스화되면 "p"를 meth1과 meth2로 전달할 필요가 없습니다.

2

[주의 :. 내 대답은 파이썬 특정하지 않습니다]

내가 전체 코드는 매개 변수의이 종류는 "바람둥이 매개 변수"라고 기억 해요. 그러나 "tramp parameter"에 대한 인터넷 검색은 많은 결과를 반환하지 않습니다. 매개 변수를 부정 기선하기

어떤 대안이 포함될 수 있습니다

  • 데이터를 착용 할 것 (글로벌 데이터와 유사) 클래스의 정적 변수에 데이터를 넣어 전역 변수
  • 의 데이터를 넣어
  • 는 의사 전역 변수 클래스의 인스턴스 변수 : 싱글 뒤에 숨겨진, 또는 의존성 주입 메커니즘

개인적으로, 둘 이상의 매개 변수가없는 한 부랑불 매개 변수는 신경 쓰지 않습니다. 즉 ... 대신 내가 원하는 것 ... ...

import a 
p1 = some_command_line_argument_value 
p2 = another_command_line_argument_value 
p3 = a_further_command_line_argument_value 
a.meth1(p1, p2, p3) 

당신의 예는 나를 위해 OK,하지만 난 좋아하지 않을

import a 
p = several_command_line_argument_values 
a.meth1(p) 

... meth2가 있다고 결정하면 때문에 그것은 이전보다 더 많은 데이터를 원합니다. 이미 전달 된 원래의 매개 변수에서이 여분의 데이터를 추출 할 수 있다면 더 편할 것입니다. 따라서 meth1을 편집 할 필요가 없습니다.

+0

-1 : 전역 변수는 최후가 아니라 마지막이어야합니다. –

+1

목록이 우선 순위에 있지 않습니다. – ChrisW

7

프로그램과 관련된 유형의 개체를 만들고 각 개체와 관련된 명령 줄 옵션을 저장합니다. 예 :

import WidgetFrobnosticator 
f = WidgetFrobnosticator() 
f.allow_oncave_widgets = option_allow_concave_widgets 
f.respect_weasel_pins = option_respect_weasel_pins 

# Now the methods of WidgetFrobnosticator have access to your command-line parameters, 
# in a way that's not dependent on the input format. 

import PlatypusFactory 
p = PlatypusFactory() 
p.allow_parthenogenesis = option_allow_parthenogenesis 
p.max_population = option_max_population 

# The platypus factory knows about its own options, but not those of the WidgetFrobnosticator 
# or vice versa. This makes each class easier to read and implement. 
+0

안녕 데이비드, 나는 너와 스티브의 대답을 받아들이는 사이에 찢겼다. 둘 다 내 질문에 답하지만 Steve 's는 모든 인스턴스에서 동일한 동작을 수행 할 동작을 구현합니다. 하나 이상의 답변을 수락 할 수있는 방법이 있었으면 좋겠어요! – Vince

1

개체의 경우 가장 적절한 정보는 개체 자체의 속성이기 때문에 매개 변수 목록은 일반적으로 매우 작아야합니다.이를 처리하는 표준 방법은 객체 속성을 구성한 다음 해당 객체의 적절한 메소드를 호출하는 것입니다. 이 경우 pa의 속성으로 설정하십시오. 너 meth2p가 설정되지 않은 경우 불평해야합니다.

관련 문제