2017-01-07 4 views
7

필자는 코드 전체에서 다른 단위로 사용되는 값을 가지고있다. 예 : BYTES 수의 버퍼 크기를 나타내지 만, KB 또는 MB로 크기를 참조하는 많은 곳에서 사용됩니다 (이것은 실제 사용 사례가 아닌 단지 예일뿐입니다).파이썬의 int 값에 속성 추가하기

우아함과 사용 편의성을 고려하여 명시적인 전환 (예 : size/1024 또는 b_to_mb(size))을 피하고 싶습니다. 그 이유는 매우 다양한 곳에서 필요하기 때문입니다.

나는 변환을 쉽게 (x.kb 또는 x.mb) 만드는 속성으로 달성 할 수 있다고 생각하고 호출자가 저장된 실제 값의 단위를 알지 못하게합니다.

내 코드는 다음과 같습니다

s = BufferSize(500000) 
s.kb 
=> 488.28125 # ok 
s.mb 
=> 0.476837158203125 # ok 
type(s + BufferSize(0)) 
=> int # type lost... 

는 산술 연산이 유형을 보존 확인하는 방법이 있나요 :

class BufferSize(int): 
    @property 
    def b(self): 
     return int(self) 
    @property 
    def kb(self): 
     return self.b/1024 
    @property 
    def mb(self): 
     return self.kb/1024 

이 내가 산술 연산자를 사용 할 때까지 작동? 즉, 그들 모두를 무시하는 것 말고 다른 것입니까?

아니면 원래의 문제를 해결하는 다른 방법이 더 좋을까요?

+0

실수 킬로바이트 또는 무언가의 양에 버퍼 크기를 추가하지 않도록 내가 int를 포장하는 대신 INT에서 상속 권하고 싶습니다. 산술 연산자는 개별적으로 정의해야합니다. 그다지 의미있는 것은 없습니다. 당신은 그들 모두를 정의 할 필요가 없다. – user2357112

+3

일반 단위 조작에 대해서는 [Pint] (https://pint.readthedocs.io/en/0.7.2/)를 참조하십시오. –

+1

@ PeterWood Pint는이 문제를 해결하는 데 가장 적합한 도구입니다. 감사. – shx2

답변

2

글쎄, 그것은 너무 많은,int의 마법 방법의 결과 캐스트 랩 /로 다시 구현 아니라 적어도 그 int의를 돌려주는 ... 모든 이들의 불행하게도. 장식품이나 메타 클래스를 사용하여 다소 빨리 처리 할 수 ​​없다면 궁금 할 것입니다.

class BufferSize(int): 
    @property 
    def b(self): 
     return int(self) 
    @property 
    def kb(self): 
     return self.b/1024 
    @property 
    def mb(self): 
     return self.kb/1024 

    def __add__(self, *args, **kwds): 
     return BufferSize(super(BufferSize, self).__add__(*args, **kwds)) 

v = BufferSize(1) + BufferSize(2) 

print v, type(v) 

출력 :

3 <class '__main__.BufferSize'> 

은 또한 자체를 int로 직접 속성을 추가하는 방법에 대한 생각,하지만 빠른 테스트는 배제.

>>> int.b = "b" 

출력 :

can't set attributes of built-in/extension type 'int'