2017-01-07 71 views
7

Farklı birimlerde kodumun genelinde yaygın olarak kullanılan bir değere sahibim. Örneğin. BYTES sayısında arabellek boyutunu temsil eden, ancak KB veya MB olarak boyutuna başvuran birçok yerde (bu yalnızca benim örneğim, gerçek kullanım durumum değil).Python'da bir int değerine özellik ekleme

Zarafet ve kullanım kolaylığı için, çok farklı yerlerde ihtiyaç duyulduğundan, açık dönüşümlerden (örneğin, size/1024 veya b_to_mb(size)) kaçınmak istiyorum.

Dönüşümü kolaylaştıran (x.kb veya x.mb) özellikleriyle bunu gerçekleştirebileceğimi düşündüm ve aynı zamanda arayanın depolanan gerçek değer biriminden habersiz olmasını sağlar.

Benim kod şöyle görünür:

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

aritmetik işlemler türünü sürdürebilmek amacıyla bir yolu var mı:

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 

Bu benim aritmetik operatörleri kullanabilirsiniz kadar çalışıyor? Yani, her birini geçersiz kılmaktan başka?

Veya orijinal sorunu çözmek için belki farklı ve daha iyi bir yol?

+0

yanlışlıkla kilobayt falan bir miktar bir BufferSize katmayan bu yüzden, bir int sarma yerine int devralma öneriyoruz. Aritmetik operatörler için, bunları ayrı ayrı tanımlamanız gerekir. O kadar da anlamlı olmayanlar var; hepsini tanımlamanıza gerek yok. – user2357112

+3

Genel birimlerin manipülasyonları için [Pint] 'e (https://pint.readthedocs.io/en/0.7.2/) bakın. –

+1

@PeterWood Pint kesinlikle bu sorun için doğru bir araçtır. Teşekkürler. – shx2

cevap

2

Eh, o kadar çok,int 'ın sihirli yöntemlerin sonuçları döküm sarma/olarak tekrar uygulamasını değil, en azından o int s dönmek olduğunu .. Bütün bunlardan maalesef. Bunu biraz hızlandırmak için bir dekoratör veya metaclass kullanamazsanız merak ediyorum.

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) 

çıkışı:

3 <class '__main__.BufferSize'> 

Ben de kendisini int doğrudan özelliğini ekleyerek düşündüm ama hızlı bir deney olduğunu dışladı.

>>> int.b = "b" 

çıkışı:

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