2011-08-16 2 views
11

나는 엔진 전체에서 데이터베이스의 스키마를 찾아야하는 응용 프로그램을 작성 중입니다. 이를 위해 Python을 사용하여 작은 데이터베이스 어댑터를 작성했습니다. 우선 필요한 기능을 설명하는 기본 클래스를 작성한 다음이 기본 클래스에서 상속 한 클래스를 사용하여 구현합니다. 길을 따라, 저는이 모든 클래스에서 액세스 할 수 있어야하는 상수를 구현해야합니다. 이러한 상수 중 일부는 C 스타일 비트 OR을 사용하여 결합해야합니다.Python에서 상수 생성에 관한 규칙

내 질문

  1. 같은 상수를 공유하는 표준 방법은 무엇입니까?
  2. 결합 할 수있는 상수를 만드는 올바른 방법은 무엇입니까? 나는 C가 허용하는 MAP_FIXED | MAP_FILE | MAP_SHARED 스타일 코드를 언급하고있다.

전자의 경우, 모든 상수가 먼저 모듈에 들어간 스레드를 발견했습니다. 후자의 경우, 나는 간단히 불리언을 사용하는 것을 생각했다. 이 두 가지 모두 너무 들떠 보였다. 나는 이것이 매우 일반적인 요구 사항이라고 생각하며, 좋은 방법이 실제로 존재해야한다고 생각합니다!

답변

3

종종 전역 수준에서 상수를 발견하며 거기에 존재하는 몇 가지 변수 중 하나입니다. 인스턴스 액세스 클래스 변수로 첨부 모듈과 다른 사람에 넣어 일부 사람들이이

class Const: 
    x = 33 

Const.x 

같은 dicts 또는 개체를 사용하여 상수 네임 스페이스를 쓰는 사람들도 있습니다. 대부분의 경우 개인적인 취향이지만, 몇 가지 글로벌 변수만으로는 그다지 큰 상처를 줄 수 없습니다.

14

이러한 상수를 공유하는 표준 방법은 무엇입니까?

표준 라이브러리 전체에서 가장 일반적인 방법은 상수를 UPPER_CASE_WITH_UNDERSCORES 이름을 사용하여 모듈 수준 변수로 정의하는 것입니다.

결합 할 수있는 상수를 만드는 올바른 방법은 무엇입니까? 나는 MAP_FIXED | MAP_FILE | C가 허용하는 MAP_SHARED 스타일 코드.

C와 동일한 규칙이 적용됩니다. 각 상수 값은 단일 고유 비트, 즉 2의 제곱 (2, 4, 8, 16, ...)에 해당하는지 확인해야합니다.

대부분의 시간을, 사람들은 이것에 대한 진수 숫자를 사용 : 파이썬에서

OPTION_A = 1 << 0 
OPTION_B = 1 << 1 
OPTION_C = 1 << 2 
# ... 

:

OPTION_A = 0x01 
OPTION_B = 0x02 
OPTION_C = 0x04 
OPTION_D = 0x08 
OPTION_E = 0x10 
# ... 

일부 동적으로 시프트 연산자를 사용하여 상수 값을 계산, 더 많은 사람이 읽을 수있는 스타일을 선호 이진 표기법을 사용하여이 사실을 훨씬 더 분명하게 만들 수도 있습니다.

OPTION_A = 0b00000001 
OPTION_B = 0b00000010 
OPTION_C = 0b00000100 
OPTION_D = 0b00001000 

B 이 표기법은 길고 읽기가 어려우므로 16 진수 또는 2 진 시프트 표기법을 사용하는 것이 좋습니다.

11

일반적으로 상수는 모듈 수준입니다.PEP 8에서 :

상수

상수는 일반적으로 모듈 레벨에서 정의 및 밑줄 단어 분리와 모두 대문자로 기록됩니다. 예에는 MAX_OVERFLOW 및 TOTAL이 포함됩니다.

클래스 수준에서 상수를 원하면 클래스 속성으로 정의하십시오. 다른 예를 원하는 경우도, 너무 비트 단위 인수 스타일을 사용하는 re 모듈 :

OPTIONS = {} 

# A function to add (register) an option. 
def register_option(name): 
    return OPTIONS.setdefault(name, 1 << len(OPTIONS)) 

# A function to test if an option exist. 
def has_option(options, name): 
    return bool(options & name) 

# All my option defined here. 
FOO = register_option('FOO') 
BAR = register_option('BAR') 
FOOBAR = register_option('FOOBAR') 


# Test if an option figure out in `ARG`. 
ARG = FOO | BAR 
print has_option(ARG, FOO) 
# True 
print has_option(ARG, BAR) 
# True 
print has_option(ARG, FOOBAR) 
# False 

N.B :

2

일반적으로 이름은 UPPERCASE_WITH_UNDERSCORE이며 일반적으로 모듈 수준이지만 가끔씩은 자신의 클래스에 살고 있습니다.

class PowTwoConstants(object): 
    def __init__(self, items): 
     self.names = items 
     enum = 1 
     for name in items: 
      setattr(self, name, enum) 
      enum <<= 1 

constants = PowTwoConstants('ignore_case multiline newline'.split()) 
print constants.newline # prints 4 

당신이 수준을 모듈에 그 상수를 수출 할 수있게하려면 (또는 다른 네임 스페이스 : 같은 두 가지의 힘이 될 필요가있는 것으로서 - 수업 시간에 할 수있는 한 가지 이유는 값이 특별한 경우이다) 당신은 클래스에 다음을 추가 할 수 있습니다

def export(self, namespace): 
     for name in self.names: 
      setattr(namespace, name, getattr(self, name)) 

다음

import sys 
constants.export(sys.modules[__name__])