2012-06-26 4 views
1

자바로 작성된 파이썬으로 라이브러리를 작성해야한다. 자바 배경 파이썬에서 오는 것은 나에게 조금 어려운 시간을주고있다. 나는 뭔가를하고 오른쪽 파이썬 방법을 선택 붙어 있어요 ..파이썬에서 파이썬으로 파이썬 코드 재 작성하기

그래서, 내 자바 코드가 같은 것입니다 :

import java.util.Collection; 

public abstract class MyEnumBaseClass 
{ 
    protected int value; 
    protected String description = null; 

    protected MyEnumBaseClass(int iValue, String iDescription) 
    { 
     value = iValue; 
     description = iDescription; 
    } 

    public int getValue() 
    { 
     return value; 
    } 

    public String getDescription() 
    { 
     return description; 
    } 

    protected static MyEnumBaseClass getEnum(Collection<MyEnumBaseClass> iter, int value) 
    { 
     for (MyEnumBaseClass enumObj : iter) 
     { 
      if (enumObj.getValue() == value) 
      { 
       return enumObj; 
      } 
     } 
     return null; 
    } 
} 



import java.util.ArrayList; 
import java.util.Collection; 

public class MyEnumClass extends MyEnumBaseClass 
{ 
    private final static Collection<MyEnumBaseClass> enumList = new ArrayList<MyEnumBaseClass>(); 

    public final static int       ERROR1  = 1; 
    public final static int       ERROR2  = 2; 
    public final static int       ERROR3  = 3; 
    public final static int       ERROR4  = 4; 

    public final static MyEnumClass     ErrorEnum1 = new MyEnumClass(ERROR1, "ERROR1"); 
    public final static MyEnumClass     ErrorEnum2 = new MyEnumClass(ERROR2, "ERROR1"); 
    public final static MyEnumClass     ErrorEnum3 = new MyEnumClass(ERROR3, "ERROR1"); 
    public final static MyEnumClass     ErrorEnum4 = new MyEnumClass(ERROR4, "ERROR1"); 

    protected MyEnumClass(int iValue, String iDescription) 
    { 
     super(iValue, iDescription); 
    } 

    public static int getCount() 
    { 
     return enumList.size(); 
    } 

    public static Collection<MyEnumBaseClass> getList() 
    { 
     return enumList; 
    } 

    public static MyEnumBaseClass getEnum(int value) 
    { 
     return getEnum(enumList, value); 
    } 
} 

내가 파이썬에서이 뭔가를 쓰고 싶어합니다. 나는 두 언어가 완전히 다른 것을 이해합니다. 정확한 코드를 복제하고 싶지는 않지만 파이썬에서 Java 코드가 제공하는 기능을 제공하는 것을 작성하고 싶습니다. 내가 알고 싶어

# MODULE MYENUMBASECLASS::: 

class MyEnumBaseClass(object): 

    def __init__(self, iValue, iDescription, ui = None): 
     self._value = iValue 
     self._description = iDescription 

    def getValue(self): 
     return self._value 

    def getDescription(self): 
     return self._description 

    @classmethod 
    def getEnum(cls, value, itr): 
     for enumObj in itr: 
      if enumObj.getValue() == value: 
       return enumObj 
     return None 


# MODULE: ENUMS::: 
from MyEnumBaseClass import MyEnumBaseClass 

__all__ = ["MyEnumClassConstants", "MyEnumClass", "MyEnums"] 
_enumList = [] 

class MyEnumClassConstants(object): 
    ERROR1 = 1 
    ERROR2 = 2 
    ERROR3 = 3 
    ERROR4 = 4 

class MyEnumClass(MyEnumBaseClass): 
    def __init__(self, v, d, ui): 
     global _enumList 
     super(MyEnumClass, self).__init__(v, d, ui) 
     _enumList.append(self) 

    @staticmethod 
    def getCount(): 
     return len(_enumList) 

    @staticmethod 
    def getList(): 
     return _enumList 

    @classmethod 
    def getEmum(cls, value, itr = None): 
     return super(MyEnumClass, cls).getEnum(value, _enumList) 


class MyEnums(object): 
    ErrorEnum1 = MyEnumClass(MyEnumClassConstants.ERROR1, "ERROR1"); 
    ErrorEnum2 = MyEnumClass(MyEnumClassConstants.ERROR2, "ERROR2"); 
    ErrorEnum3 = MyEnumClass(MyEnumClassConstants.ERROR3, "ERROR3"); 
    ErrorEnum4 = MyEnumClass(MyEnumClassConstants.ERROR4, "ERROR4"); 

: 그것을 수행하는 올바른 파이썬 방법

  1. 그래서 내가 좋아하는 뭔가를 함께했다?

  2. MyEnums 클래스의 ErrorEnum1,2,3,4 및 상수를 모듈 변수로 옮기고 싶었습니다. 하지만 그 방법으로는 내 에 모두 긴 목록을 가지고 있습니다. 모두입니다. 또한 다른 모듈에서 Enums 모듈을 가져올 때 변수 이름 충돌의 위험이 있습니다 (다른 일부 Enums2 모듈에도 ErrorEnum1,2,3이있을 수 있습니다.)하지만 큰 문제는 아닙니다 .Enums.ErrorEnum1과 Enums2를 항상 사용할 수 있습니다. .ErrorEnum1). 나는 생각하고 있니?

  3. 나는 이것이 완벽하지 않다는 것을 안다. (내 첫 번째 파이썬 코드). 그래서 나는 너희들에게 나에게 아이디어를 주라고 초대한다. 그들이 할 수 없습니다에 대한 정말 좋은 이유이 아니라면

감사 일반적으로

+0

완전히 주제가 맞지 않지만 Java의 열거 유형을 사용하지 않은 이유가 있습니까? – poke

+0

그것에 대해 아무런 설명이 없습니다. 왜냐하면 내가 파이썬 API를 만드는이 작업을 할 때 이미 이와 같았 기 때문입니다. 이것은 SOAP 메시지에서 사용되었습니다. 그래서, 내가 이해하는 한, 내가 붙여 넣은 자바 코드는 에러 코드와 설명이 있다는 이점을 제공한다. Java Enum은 그렇지 않습니다. 또한 제거한 다른 코드가 있습니다. 여기에서 묻는 질문에는 문제가 없기 때문입니다. – Ashutosh

+0

자바에서 열거 형은 실제로는 특별한 클래스이므로 일반 클래스에서 거의 모든 것을 연결할 수 있습니다. 이 주제는 파이썬 코드에 관한 것이지 자바 코드에 관한 것이 아니기 때문에 주제가 아닙니다. 단지 궁금한 것이 었습니다 ...;) – poke

답변

5

글쎄, 난 당신이 코드가 최적보다 작은 것을 인식하고 확실히 하지 길을 가야하는 것입니다 가정합니다. 또 다른 문제는 우리가 정확히 무엇을하려고하는지 모르기 때문에 "자바 코드에서 제공하는 기능을 제공하는 파이썬으로 무언가를 쓸 수있는 방법"을 말할 수 없다는 것입니다.

  • 첫째, 왜 MyEnumBaseClassMyEnumClass을 가지고 : 즉, 하나는 아무 문제없이 제거 할 수있는 코드에서 명백한 자바 바이어스의 많은이 말했다? 하나만 가질 수 있습니다. 클래스 수와 모듈 수를 줄입니다.열거 형을 확장하려는 경우에도 코드를 단순화 한 후에 MyEnumClass이 문제없이 확장 될 수 있다는 것을 알 수 있습니다.

  • 이제는 게터와 설정자가 없습니다.. 특성을 가지고 있기 때문에 사용할 이유가 없습니다. 당신의 재산은 얻고 값을 설정할 경우, 어쨌든 속성을 사용하지 마십시오

    class MyEnumClass(object): 
        def __init__(self, value, description, ui = None): 
         self.value = value 
         self.description = description 
    
  • 바로 그러한 MyEnumClassConstantsMyEnums 상수와 같은 값을 유지하기 위해 클래스를 만드는 정말 밉다. 그냥 모듈 수준에서 몇 가지 변수를 만듭니다. 아래 항목을 수행하는 방법을 살펴 보겠습니다.

  • 또한 getEnum()은 (는) classmethod가 무엇입니까? 이것은 단순한 기능이 될 수 있으며이 모듈 내부에 있기 때문에 충돌에 대해 걱정할 필요하지 않은 :

    : 당신은 일련 번호와 몇 가지 변수를 설정하려는 경우

    def getEnum(value, itr): 
        for enumObj in itr: 
         if enumObj.value == value: 
          return enumObj 
        return None 
    
  • 것은, 당신이 unpacking idiom을 사용할 수 있습니다

    (
        ERROR1, 
        ERROR2, 
        ERROR3, 
        ERROR4 
    ) = range(1, 5) 
    
  • 이 관용구도 열거 목록을 생성하는 데 사용할 수 있습니다

    _enums = (
        ErrorEnum1, 
        ErrorEnum2, 
        ErrorEnum3, 
        ErrorEnum4 
    ) = (
        MyEnumClass(ERROR1, "ERROR1"), 
        MyEnumClass(ERROR2, "ERROR2"), 
        MyEnumClass(ERROR3, "ERROR3"), 
        MyEnumClass(ERROR4, "ERROR4") 
    ) 
    
  • 것은 숫돌 되려면 t, 나는 행복하게 _enums을 모듈의 공개 멤버로 남겨 둘 것이지만, 우리는 getEnum()으로했던 것처럼 다른 클래스 메소드와 함께하자 : 모듈의 함수로 선언한다 :

    def getCount(): 
        return len(_enums) 
    
    def getList(): 
        return _enums 
    
  • 우리는 심지어 기본 매개 변수를 변경하여 getEnum()을 향상시킬 수 있습니다 : 나는 또한 행복하게 여기 __all__ 선언을 금지 할

    def getEnum(value, itr=_enums): 
        for enumObj in itr: 
         if enumObj.value == value: 
          return enumObj 
        return None 
    
  • . 인터페이스의 일부가 아닌 유일한 것은 _enums 튜플이고, 앞에 _이 있으며, PEP-8에 따르면, 외부에서 사용하면 안된다는 것을 의미합니다. 그러나 우리는 그것이 머무를 것이라고 말한다. 인터페이스에서 MyEnumClass을 제거하지만, 잘, 당신은 그래서 그것을 떠나 그것을 사용할 수 있습니다 더 나은 것 같다

    __all__ = ["MyEnumClass", "ERROR1", "ERROR2", "ERROR3", "ERROR4", 
         "ErrorEnum1", "ErrorEnum2", "ErrorEnum3", "ErrorEnum4", 
         "getCount", "getList", "getEnum"] 
    

    : 귀하의 모듈은 더 상수와 기능을 가진 새로운 인터페이스를 가지고 있습니다. __all__은 모듈의 다른 구성 요소에 대한 액세스를 피할 수 없습니다.

    __all__ = ["MyEnumClass", "ERROR1", "ERROR2", "ERROR3", "ERROR4", 
         "ErrorEnum1", "ErrorEnum2", "ErrorEnum3", "ErrorEnum4", 
         "getCount", "getList", "getEnum"] 
    
    class MyEnumClass(object): 
        def __init__(self, value, description, ui = None): 
         self.value = value 
         self.description = description 
    
    (
        ERROR1, 
        ERROR2, 
        ERROR3, 
        ERROR4 
    ) = range(1, 5) 
    
    
    _enums = (
        ErrorEnum1, 
        ErrorEnum2, 
        ErrorEnum3, 
        ErrorEnum4 
    ) = (
        MyEnumClass(ERROR1, "ERROR1"), 
        MyEnumClass(ERROR2, "ERROR2"), 
        MyEnumClass(ERROR3, "ERROR3"), 
        MyEnumClass(ERROR4, "ERROR4") 
    ) 
    
    def getCount(): 
        return len(_enums) 
    
    def getList(): 
        return _enums 
    
    def getEnum(value, itr=_enums): 
        for enumObj in itr: 
         if enumObj.value == value: 
          return enumObj 
        return None 
    

    (EDITED)이 정말별로 간단하다 : 그것은 단지 문서이 같은

최종 결과가 될 것입니다 뭔가를 변경합니다. 오류 코드를 만들면 ERROR1, ERROR2 등의 변수를 만들뿐입니다. 클래스에는 클래스가없고 함수가없고 변수에 값만 있습니다.사실, 오류 코드를 작성하는 아이디어조차도 부적절한 것 같습니다. Zen of Python에서 설명한대로 errors should never pass silently (또는 Eric Raymond의 Unix 철학에 따르면 when you must fail, fail noisily and as soon as possible) 예외를 작성하는 것이 좋습니다. 그럼에도 불구하고, 내가 한 변화가 파이썬 작성의 좀 더 정확한 맛을 줄 수 있다고 확신합니다.

이런 식으로 일하는 것에 대해 가려움을 느끼 겠지만, 가장 좋은 방법이라고 생각합니다. 어떤 사람들은 나에게 어떤 점에서는 동의하지 않을 수도 있지만 아이디어는 제시된 것입니다. 나는 대부분 자바 개발자이지만, 언어의 음악에 맞춰 춤을 추는 것이 중요합니다. 외국 개념을 강요하려고하지 마십시오. 마지막으로

, 몇 가지 중요한 참조 :

  • PEP-20 - 파이썬의 선 : 파이썬과 파이썬으로 개발하는 핵심 가치의 다소 시적 목록.
  • PEP-8 - 파이썬 스타일 가이드. 바로 지금을 읽으십시오.
  • Python is not Java - Python에서 부적절한 Java 습관을 피하는 가장 좋은 지침 중 하나입니다.
+0

다른 참조를 추가하고 마지막 단락 중 하나를 편집하여 몇 가지 중요한 사항을 추가했습니다. – brandizzi

+0

이것은 비누 취급 오류입니다. 예외는 호출 스택에서 한 수준 위로 발생합니다. 이것은 비누 메시지 구문 분석에서 오는 오류 상태를 나타냅니다. – Ashutosh

+0

@Ashutosh 글쎄, 지금은 더 의미가있어. :) – brandizzi

0
  • 는 파이썬 클래스 속성은 대중 남아 있습니다. 재산 개인이어야합니다

  • , getProperty 메소드보다 @property 장식을 사용하는 것이 더 파이썬입니다.

.

class MyEnumBaseClass(object): 
    def __init__(self, value, description, ui=None): 
     self.value = value 
     self._description = description 
     self.ui = [] if ui is None else ui 

    @property 
    def description(self): 
     return self._description 

    @classmethod 
    def get_enum(cls, value, itr): 
     for enumObj in itr: 
      if enumObj.value == value: 
       return enumObj 
     return None 
+0

몰랐다. :) 감사. – Ashutosh

0

보다 파이썬 방법 :

class EnumValue(object): 
    def __init__(self, value, description): 
     self.value = value 
     self.description = description 

class EnumType(object): 
    @classmethod 
    def lookup(cls, value): 
     for error in cls.VALUES: 
      if error.value == value: 
       return value 
     raise ValueError(value)  

class MyErrors(EnumType): 
    ERROR1 = EnumValue(1, "Simple Errors") 
    ERROR2 = EnumValue(2, "Bigger Errors") 
    ERROR3 = EnumValue(3, "Really Big Errors") 

    VALUES = [ERROR1, ERROR2, ERROR3] 
+0

MyEnumBaseClass를 확장하는 MyEnumClass와 같은 수천 개의 errorEnumClass가 있으므로 MyEnumBaseClass가 별도로 필요합니다. 그래서, 조회 (getEnum) 메서드를 MyErrors (enums)로 옮길 수 없습니다. 또한 다른 모듈/클래스에서 비교하거나 사용할 수 있도록 상수가 필요합니다. 나는 이것이 의미가 있고 제약을 설명하기를 바란다. – Ashutosh

+0

@Ashutosh, 수천? 이케아! 공통 요소를 기본 클래스로 가져 오는 것은 쉽습니다 (편집 참조). MyErrors.ERROR1.value로 상수에 접근 할 수 있지만, 필요하다면 의심 스럽다. 항상 EnumValue 객체이거나 항상 정수를 사용해야합니다. 하나를 골라서 붙잡아 라. –

+0

방금 ​​오류 클래스의 수를 10 또는 20 배로 곱한 것을 깨달았습니다. – Ashutosh

관련 문제