फ़ाइल आकार के मानव पठनीय संस्करण प्राप्त करने के लिए पुन: प्रयोज्य पुस्तकालय?


238

वेब पर विभिन्न स्निपेट्स हैं जो आपको बाइट्स आकार से मानव पठनीय आकार को वापस करने के लिए एक फ़ंक्शन देंगे:

>>> human_readable(2048)
'2 kilobytes'
>>>

लेकिन क्या एक पायथन पुस्तकालय है जो इसे प्रदान करता है?


2
मुझे लगता है कि यह "एक पुस्तकालय की आवश्यकता के लिए बहुत छोटा कार्य" शीर्षक के तहत आता है। यदि आप जल्दी के लिए स्रोत को देखते हैं। फ़ाइल का आकार, कोड की एक दर्जन लाइनों के साथ केवल एक ही कार्य है। और यहां तक ​​कि इसे कॉम्पैक्ट किया जा सकता है।
बेन ब्लैंक

8
लाइब्रेरी का उपयोग करने का लाभ यह है कि आमतौर पर इसका परीक्षण किया जाता है (इसमें ऐसे परीक्षण शामिल हैं जो किसी बग को संपादित करने पर मामले में चलाए जा सकते हैं)। यदि आप परीक्षण जोड़ते हैं, तो यह अब 'कोड की दर्जनों लाइनें' नहीं है :-)
श्रीधर रत्नाकुमार

अजगर समुदाय में पहिया को फिर से आविष्कार करने की मात्रा पागल और हास्यास्पद है। बस ls -h /path/to/file.ext काम करेगा। यह कहते हुए कि, स्वीकृत उत्तर अच्छा काम कर रहा है। कूडो।
एडवर्ड आंग

जवाबों:


522

उपरोक्त "संबोधित करने के लिए एक कार्य के लिए एक पुस्तकालय की आवश्यकता के लिए बहुत छोटा काम" एक सीधा कार्यान्वयन द्वारा मुद्दा:

def sizeof_fmt(num, suffix='B'):
    for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
        if abs(num) < 1024.0:
            return "%3.1f%s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f%s%s" % (num, 'Yi', suffix)

समर्थन:

  • वर्तमान में सभी ज्ञात द्विआधारी उपसर्ग
  • नकारात्मक और सकारात्मक संख्या
  • 1000 Yobibytes से बड़ी संख्या
  • मनमानी इकाइयां (शायद आप गिबीबिट्स में गिनना पसंद करते हैं!)

उदाहरण:

>>> sizeof_fmt(168963795964)
'157.4GiB'

फ्रेड सेरा द्वारा


4
संख्या और इकाई के बीच एक स्थान होना चाहिए। यदि आप html या लेटेक्स को आउटपुट कर रहे हैं तो यह एक नॉन-ब्रेकिंग-स्पेस होना चाहिए।
14

3
सिर्फ एक विचार, लेकिन किसी भी (?) के लिए प्रत्यय B(बाइट्स के अलावा अन्य इकाइयों के लिए) के 1000.0बजाय आप चाहते हैं कि कारक 1024.0नहीं के बजाय होगा ?
एंथ्रोपिक

5
यदि आप दशमलव घटक की सटीकता बढ़ाना चाहते हैं, तो आप 1जो भी परिशुद्धता चाहते हैं, उसे लाइनों ४ और ६ पर बदल दें।
मैथ्यू जी

44
यकीन है कि अच्छा होगा अगर इस "बहुत छोटे कार्य" पर सभी पुनरावृत्ति को पकड़ लिया गया और परीक्षण के साथ एक पुस्तकालय में संलग्न कर दिया गया।
डर।

6
@ MD004 यह दूसरा तरीका है। उपसर्गों को इस तरह परिभाषित किया जाता है कि 1 KB = 1000 B और 1 KiB = 1024 B.
अगुरार

116

एक पुस्तकालय जिसमें वह सभी कार्यक्षमता होती है जो ऐसा लगता है कि आप खोज रहे हैं humanizehumanize.naturalsize()लगता है कि सब कुछ आप के लिए देख रहे हैं।


9
कुछ उदाहरण ओपी से डेटा का उपयोग कर: humanize.naturalsize(2048) # => '2.0 kB' ,humanize.naturalsize(2048, binary=True) # => '2.0 KiB' humanize.naturalsize(2048, gnu=True) # => '2.0K'
RubenLaguna

32

यहाँ मेरा संस्करण है। यह फॉर-लूप का उपयोग नहीं करता है। इसमें निरंतर जटिलता है, ओ ( 1 ), और सिद्धांत में है कि यहां उन उत्तरों की तुलना में अधिक कुशल हैं जो एक लूप का उपयोग करते हैं।

from math import log
unit_list = zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2])
def sizeof_fmt(num):
    """Human friendly file size"""
    if num > 1:
        exponent = min(int(log(num, 1024)), len(unit_list) - 1)
        quotient = float(num) / 1024**exponent
        unit, num_decimals = unit_list[exponent]
        format_string = '{:.%sf} {}' % (num_decimals)
        return format_string.format(quotient, unit)
    if num == 0:
        return '0 bytes'
    if num == 1:
        return '1 byte'

यह स्पष्ट करने के लिए कि क्या चल रहा है, हम स्ट्रिंग प्रारूपण के लिए कोड को छोड़ सकते हैं। यहां वे लाइनें हैं जो वास्तव में काम करती हैं:

exponent = int(log(num, 1024))
quotient = num / 1024**exponent
unit_list[exponent]

2
जब आप इस तरह के एक छोटे कोड को अनुकूलित करने के बारे में बात करते हैं, तो / elif / if का उपयोग क्यों नहीं करते हैं? जब तक आप नकारात्मक फ़ाइल आकारों की अपेक्षा नहीं करते हैं, तब तक अंतिम चेक संख्या == 1 अनावश्यक है। अन्यथा: अच्छा काम, मुझे यह संस्करण पसंद है।
ted

2
मेरा कोड निश्चित रूप से अधिक अनुकूलित हो सकता है। हालांकि, मेरा कहना यह था कि इस कार्य को निरंतर जटिलता के साथ हल किया जा सकता है।
जौक्टी

37
छोरों के साथ उत्तर भी ओ (1) हैं, क्योंकि छोरों के लिए बाध्य हैं - उनका संगणना समय इनपुट के आकार के साथ स्केल नहीं करता है (हमारे पास एसआई उपसर्ग नहीं है)।
थॉमस माइनर

1
शायद स्वरूपण के लिए एक अल्पविराम जोड़ना चाहिए, इसलिए 1000जैसा दिखाई देगा 1,000 bytes
iTayb

3
ध्यान दें कि पायथन 3 का उपयोग करते समय, ज़िप एक पुनरावृत्ति देता है, इसलिए आपको इसे सूची () के साथ लपेटने की आवश्यकता है। unit_list = list(zip(['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], [0, 0, 1, 2, 2, 2]))
21'46 पर डोनर्ब

30

पायथन 3.6+ में निम्नलिखित काम करता है, मेरी राय में, यहाँ पर उत्तर समझने में सबसे आसान है, और आपको इस्तेमाल की गई दशमलव स्थानों की मात्रा को अनुकूलित करने की सुविधा देता है।

def human_readable_size(size, decimal_places=3):
    for unit in ['B','KiB','MiB','GiB','TiB']:
        if size < 1024.0:
            break
        size /= 1024.0
    return f"{size:.{decimal_places}f}{unit}"

26

जबकि मुझे पता है कि यह सवाल प्राचीन है, मैं हाल ही में एक संस्करण के साथ आया था जो लूप से बचा जाता है, log2आकार के क्रम को निर्धारित करने के लिए उपयोग करता है जो एक शिफ्ट के रूप में और एक इंडेक्स की सूची में दोगुना होता है:

from math import log2

_suffixes = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']

def file_size(size):
    # determine binary order in steps of size 10 
    # (coerce to int, // still returns a float)
    order = int(log2(size) / 10) if size else 0
    # format file size
    # (.4g results in rounded numbers for exact matches and max 3 decimals, 
    # should never resort to exponent values)
    return '{:.4g} {}'.format(size / (1 << (order * 10)), _suffixes[order])

अच्छी तरह से अपनी पठनीयता के लिए अनहोनी माना जा सकता है, हालांकि :)


1
जबकि मुझे log2 चीज़ पसंद है, आपको आकार == 0 को संभालना चाहिए!
मार्टी निको

आप या तो रैप करने के लिए की जरूरत है sizeया (1 << (order * 10)में float()अंतिम पंक्ति (अजगर 2 के लिए) में।
हार्वे

FYI करें: कुछ को import mathवहाँ की आवश्यकता हो सकती है ।
21

@monsto सच, कहा :)
akaIDIOT

प्यार कितना कॉम्पैक्ट है! साझा करने के लिए धन्यवाद।
जॉन क्रॉफर्ड

17

वहाँ हमेशा उन लोगों में से एक हो गया है। खैर आज यह मैं हूँ। यदि आप फ़ंक्शन हस्ताक्षर की गणना करते हैं तो यहां एक-लाइनर समाधान - या दो लाइनें हैं।

def human_size(bytes, units=[' bytes','KB','MB','GB','TB', 'PB', 'EB']):
    """ Returns a human readable string reprentation of bytes"""
    return str(bytes) + units[0] if bytes < 1024 else human_size(bytes>>10, units[1:])

>>> human_size(123)
123 bytes
>>> human_size(123456789)
117GB

1
FYI करें, आउटपुट हमेशा नीचे होगा।
wp-overwatch.com

1
यह बेहतर नहीं होगा कि डिफ़ॉल्ट तर्क के रूप में सूची का उपयोग करने से बचने के लिए विधि के अंदर इकाइयों के लिए डिफ़ॉल्ट सूची को असाइन किया जाए? (और का उपयोग कर units=Noneके बजाय)
Imanol

3
@ImanolEizaguirre सर्वोत्तम प्रथाओं में कहा गया है कि यह एक अच्छा विचार है जैसा कि आपने सुझाव दिया है, इसलिए आप अनजाने में एक कार्यक्रम में बग का परिचय नहीं देते हैं। हालाँकि, यह फ़ंक्शन जैसा कि लिखा गया है, सुरक्षित है क्योंकि इकाइयों की सूची में कभी भी हेरफेर नहीं किया जाता है। यदि इसमें हेरफेर किया गया था, तो परिवर्तन स्थायी होगा, और बाद के किसी भी फ़ंक्शन कॉल को यूनिट तर्क के लिए डिफ़ॉल्ट तर्क के रूप में सूची का एक हेरफेर किया गया संस्करण प्राप्त होगा।
wp-overwatch.com

पायथन 3 के लिए, यदि आप एक दशमलव बिंदु चाहते हैं, तो इसके बजाय इसका उपयोग करें: `` human_size (fsize, इकाइयों = ['बाइट्स', 'KB', 'MB', 'GB', 'TB', 'PB' को परिभाषित करें। 'EB']]: "{: .2f} {}" लौटाएँ। प्रारूप (फ्लोट (fsize), इकाइयों [0]) यदि fsize <1024 और human_size (fsize / 1024, इकाइयों [1:]] `` `
ओमर

15

यदि आप Django स्थापित का उपयोग कर रहे हैं, तो आप filesizeformat भी आज़मा सकते हैं :

from django.template.defaultfilters import filesizeformat
filesizeformat(1073741824)

=>

"1.0 GB"

1
मेरे लिए एक नकारात्मक पहलू यह है कि यह GiB के बजाय GB का उपयोग करता है, भले ही यह 1024 से विभाजित हो रहा हो।
पेप्डू

9

ऐसी ही एक लाइब्रेरी है जल्दबाज़ी

>>> from hurry.filesize import alternative
>>> size(1, system=alternative)
'1 byte'
>>> size(10, system=alternative)
'10 bytes'
>>> size(1024, system=alternative)
'1 KB'

3
हालाँकि, यह लाइब्रेरी बहुत अनुकूलन योग्य नहीं है। >>> जल्दी से। आयात आकार >>> आकार (1031053) >>> आकार (3033053) '2 एम' मैं उम्मीद करता हूं कि यह दिखाएगा, उदाहरण के लिए, '2.4 एम' या '2423 के' .. धब्बेदार के बजाय। ' 2 एम '।
श्रीधर रत्नाकुमार

यह भी ध्यान रखें कि कोड को हड़बड़ी से बाहर निकालना बहुत आसान है। इसे निर्भर करें और इसे सीधे अपने कोड में डालें, यदि आप निर्भरता प्रणाली और इस तरह से काम कर रहे हैं। यह लगभग उतना ही छोटा है जितना कि स्निपेट लोग यहां प्रदान कर रहे हैं।
3

@ श्रीधररत्नाकुमार, अति-अनुमानित समस्या को कुछ समझदारी से संबोधित करने के लिए, कृपया मेरी गणितीय हैक देखें । क्या दृष्टिकोण को और बेहतर बनाया जा सकता है?
एक्यूमेनस

9

1000 या kibibytes की शक्तियों का उपयोग करना अधिक मानक-अनुकूल होगा:

def sizeof_fmt(num, use_kibibyte=True):
    base, suffix = [(1000.,'B'),(1024.,'iB')][use_kibibyte]
    for x in ['B'] + map(lambda x: x+suffix, list('kMGTP')):
        if -base < num < base:
            return "%3.1f %s" % (num, x)
        num /= base
    return "%3.1f %s" % (num, x)

PS कभी भी उस लाइब्रेरी पर भरोसा नहीं करता जो K (अपरकेस) प्रत्यय के साथ हजारों प्रिंट करता है :)


P.S. Never trust a library that prints thousands with the K (uppercase) suffix :)क्यों नहीं? कोड पूरी तरह से ध्वनि हो सकता है और लेखक सिर्फ किलो के लिए आवरण पर विचार नहीं करता है। यह आपके नियम के आधार पर किसी भी कोड को स्वचालित रूप से खारिज करने के लिए बहुत ही सुंदर लगता है ...
डगलस गास्केल

7

यह वही करेगा जो आपको लगभग किसी भी स्थिति में चाहिए, वैकल्पिक तर्क के साथ अनुकूलन योग्य है, और जैसा कि आप देख सकते हैं, बहुत अधिक स्व-दस्तावेजीकरण है:

from math import log
def pretty_size(n,pow=0,b=1024,u='B',pre=['']+[p+'i'for p in'KMGTPEZY']):
    pow,n=min(int(log(max(n*b**pow,1),b)),len(pre)-1),n*b**pow
    return "%%.%if %%s%%s"%abs(pow%(-pow-1))%(n/b**float(pow),pre[pow],u)

उदाहरण आउटपुट:

>>> pretty_size(42)
'42 B'

>>> pretty_size(2015)
'2.0 KiB'

>>> pretty_size(987654321)
'941.9 MiB'

>>> pretty_size(9876543210)
'9.2 GiB'

>>> pretty_size(0.5,pow=1)
'512 B'

>>> pretty_size(0)
'0 B'

उन्नत अनुकूलन:

>>> pretty_size(987654321,b=1000,u='bytes',pre=['','kilo','mega','giga'])
'987.7 megabytes'

>>> pretty_size(9876543210,b=1000,u='bytes',pre=['','kilo','mega','giga'])
'9.9 gigabytes'

यह कोड पाइथन 2 और पाइथन 3 दोनों संगत है। PEP8 अनुपालन पाठक के लिए एक अभ्यास है। याद रखें, यह है उत्पादन सुंदर है कि।

अपडेट करें:

यदि आपको हजारों अल्पविरामों की आवश्यकता है, तो बस स्पष्ट एक्सटेंशन लागू करें:

def prettier_size(n,pow=0,b=1024,u='B',pre=['']+[p+'i'for p in'KMGTPEZY']):
    r,f=min(int(log(max(n*b**pow,1),b)),len(pre)-1),'{:,.%if} %s%s'
    return (f%(abs(r%(-r-1)),pre[r],u)).format(n*b**pow/b**float(r))

उदाहरण के लिए:

>>> pretty_units(987654321098765432109876543210)
'816,968.5 YiB'


6

जल्दी करने के लिए एक विकल्प के रूप में प्रदान की गई स्निपेट पर रिफ़िंग करना (फ़ाइलिज़ करना), यहाँ एक स्निपेट है जो प्रयुक्त उपसर्ग के आधार पर अलग-अलग सटीक संख्या देता है। यह कुछ स्निपेट्स की तरह नहीं है, लेकिन मुझे इसके परिणाम पसंद हैं।

def human_size(size_bytes):
    """
    format a size in bytes into a 'human' file size, e.g. bytes, KB, MB, GB, TB, PB
    Note that bytes/KB will be reported in whole numbers but MB and above will have greater precision
    e.g. 1 byte, 43 bytes, 443 KB, 4.3 MB, 4.43 GB, etc
    """
    if size_bytes == 1:
        # because I really hate unnecessary plurals
        return "1 byte"

    suffixes_table = [('bytes',0),('KB',0),('MB',1),('GB',2),('TB',2), ('PB',2)]

    num = float(size_bytes)
    for suffix, precision in suffixes_table:
        if num < 1024.0:
            break
        num /= 1024.0

    if precision == 0:
        formatted_size = "%d" % num
    else:
        formatted_size = str(round(num, ndigits=precision))

    return "%s %s" % (formatted_size, suffix)


4

पिछले सभी उत्तरों से आकर्षित, यहाँ मेरा इस पर ध्यान है। यह एक ऑब्जेक्ट है जो एक पूर्णांक के रूप में बाइट्स में फ़ाइल का आकार संग्रहीत करेगा। लेकिन जब आप ऑब्जेक्ट को प्रिंट करने का प्रयास करते हैं, तो आपको स्वचालित रूप से एक मानव पठनीय संस्करण मिलता है।

class Filesize(object):
    """
    Container for a size in bytes with a human readable representation
    Use it like this::

        >>> size = Filesize(123123123)
        >>> print size
        '117.4 MB'
    """

    chunk = 1024
    units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']
    precisions = [0, 0, 1, 2, 2, 2]

    def __init__(self, size):
        self.size = size

    def __int__(self):
        return self.size

    def __str__(self):
        if self.size == 0: return '0 bytes'
        from math import log
        unit = self.units[min(int(log(self.size, self.chunk)), len(self.units) - 1)]
        return self.format(unit)

    def format(self, unit):
        if unit not in self.units: raise Exception("Not a valid file size unit: %s" % unit)
        if self.size == 1 and unit == 'bytes': return '1 byte'
        exponent = self.units.index(unit)
        quotient = float(self.size) / self.chunk**exponent
        precision = self.precisions[exponent]
        format_string = '{:.%sf} {}' % (precision)
        return format_string.format(quotient, unit)

3

मुझे प्रेषक के दशमलव संस्करण की निश्चित सटीकता पसंद है , इसलिए यहां जोक्टी के उत्तर के साथ एक प्रकार का हाइब्रिड है (क्या आप जानते हैं कि आप गैर-पूर्णांक आधारों के साथ लॉग ले सकते हैं?)।

from math import log
def human_readable_bytes(x):
    # hybrid of https://stackoverflow.com/a/10171475/2595465
    #      with https://stackoverflow.com/a/5414105/2595465
    if x == 0: return '0'
    magnitude = int(log(abs(x),10.24))
    if magnitude > 16:
        format_str = '%iP'
        denominator_mag = 15
    else:
        float_fmt = '%2.1f' if magnitude % 3 == 1 else '%1.2f'
        illion = (magnitude + 1) // 3
        format_str = float_fmt + ['', 'K', 'M', 'G', 'T', 'P'][illion]
    return (format_str % (x * 1.0 / (1024 ** illion))).lstrip('0')


2

आधुनिक Django के स्वयं टेम्पलेट टैग हैं filesizeformat:

human-readableफ़ाइल आकार (जैसे '13 KB ',' 4.1 MB ',' 102 बाइट्स, इत्यादि ') का मूल्य निर्धारित करता है।

उदाहरण के लिए:

{{ value|filesizeformat }}

यदि मान 123456789 है, तो उत्पादन 117.7 एमबी होगा।

अधिक जानकारी: https://docs.djangoproject.com/en/1.10/ref/templates/builtins/#files/formformat


2

कैसे एक साधारण 2 लाइनर के बारे में:

def humanizeFileSize(filesize):
    p = int(math.floor(math.log(filesize, 2)/10))
    return "%.3f%s" % (filesize/math.pow(1024,p), ['B','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'][p])

यहाँ यह हुड के तहत काम करता है:

  1. लॉग 2 की गणना करता है (फाइल करें)
  2. निकटतम इकाई प्राप्त करने के लिए इसे 10 से विभाजित करता है। (जैसे कि यदि आकार 5000 बाइट्स है, तो निकटतम इकाई हैKb , इसलिए उत्तर X KiB होना चाहिए)
  3. file_size/value_of_closest_unitयूनिट के साथ रिटर्न ।

हालाँकि यह काम नहीं करता है यदि फ़ाइल 0 या नकारात्मक है (क्योंकि लॉग 0 और -ve संख्या के लिए अपरिभाषित है)। आप उनके लिए अतिरिक्त जांच जोड़ सकते हैं:

def humanizeFileSize(filesize):
    filesize = abs(filesize)
    if (filesize==0):
        return "0 Bytes"
    p = int(math.floor(math.log(filesize, 2)/10))
    return "%0.2f %s" % (filesize/math.pow(1024,p), ['Bytes','KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'][p])

उदाहरण:

>>> humanizeFileSize(538244835492574234)
'478.06 PiB'
>>> humanizeFileSize(-924372537)
'881.55 MiB'
>>> humanizeFileSize(0)
'0 Bytes'

नोट - Kb और KiB में अंतर है। KB का मतलब 1000 बाइट्स है, जबकि KiB का मतलब 1024 बाइट्स है। KB, MB, GB सभी 1000 के गुणक हैं, जबकि KiB, MiB, GiB आदि 1024 के सभी गुणक हैं। यहाँ के बारे में अधिक


1
def human_readable_data_quantity(quantity, multiple=1024):
    if quantity == 0:
        quantity = +0
    SUFFIXES = ["B"] + [i + {1000: "B", 1024: "iB"}[multiple] for i in "KMGTPEZY"]
    for suffix in SUFFIXES:
        if quantity < multiple or suffix == SUFFIXES[-1]:
            if suffix == SUFFIXES[0]:
                return "%d%s" % (quantity, suffix)
            else:
                return "%.1f%s" % (quantity, suffix)
        else:
            quantity /= multiple

1

नीचे आप जो खोजने जा रहे हैं, वह पहले से ही पोस्ट किए गए लोगों के बीच सबसे अच्छा प्रदर्शन या सबसे कम समाधान है। इसके बजाय, यह एक विशेष मुद्दे पर केंद्रित है, जिसमें से कई अन्य उत्तर याद आते हैं।

जब इनपुट 999_995दिया जाता है तो पूरी तरह से मामला :

Python 3.6.1 ...
...
>>> value = 999_995
>>> base = 1000
>>> math.log(value, base)
1.999999276174054

जिसे, निकटतम पूर्णांक पर काट दिया जाता है और इनपुट पर वापस लागू किया जाता है

>>> order = int(math.log(value, base))
>>> value/base**order
999.995

ऐसा लगता है कि जब तक हम उत्पादन परिशुद्धता को नियंत्रित करने के लिए आवश्यक नहीं हो जाते, तब तक हम क्या उम्मीद करते हैं । और यह तब है जब चीजें थोड़ी मुश्किल होने लगती हैं।

2 अंकों के सटीक सेट के साथ हम प्राप्त करते हैं:

>>> round(value/base**order, 2)
1000 # K

के बजाय 1M

हम उसका मुकाबला कैसे कर सकते हैं?

बेशक, हम इसे स्पष्ट रूप से जांच सकते हैं:

if round(value/base**order, 2) == base:
    order += 1

लेकिन क्या हम बेहतर कर सकते हैं? क्या हमें पता चल सकता है किorder सकता है कि अंतिम चरण करने से पहले हमें कटौती करनी चाहिए?

यह पता चला कि हम कर सकते हैं।

0.5 दशमलव गोलाई नियम को मानते हुए, उपरोक्त ifशर्त इस प्रकार है :

यहां छवि विवरण दर्ज करें

जिसके परिणामस्वरूप

def abbreviate(value, base=1000, precision=2, suffixes=None):
    if suffixes is None:
        suffixes = ['', 'K', 'M', 'B', 'T']

    if value == 0:
        return f'{0}{suffixes[0]}'

    order_max = len(suffixes) - 1
    order = log(abs(value), base)
    order_corr = order - int(order) >= log(base - 0.5/10**precision, base)
    order = min(int(order) + order_corr, order_max)

    factored = round(value/base**order, precision)

    return f'{factored:,g}{suffixes[order]}'

दे रही है

>>> abbreviate(999_994)
'999.99K'
>>> abbreviate(999_995)
'1M'
>>> abbreviate(999_995, precision=3)
'999.995K'
>>> abbreviate(2042, base=1024)
'1.99K'
>>> abbreviate(2043, base=1024)
'2K'

0

Sridhar Ratnakumarइसका उत्तर देखें , के लिए अद्यतन:

def formatSize(sizeInBytes, decimalNum=1, isUnitWithI=False, sizeUnitSeperator=""):
  """format size to human readable string"""
  # https://en.wikipedia.org/wiki/Binary_prefix#Specific_units_of_IEC_60027-2_A.2_and_ISO.2FIEC_80000
  # K=kilo, M=mega, G=giga, T=tera, P=peta, E=exa, Z=zetta, Y=yotta
  sizeUnitList = ['','K','M','G','T','P','E','Z']
  largestUnit = 'Y'

  if isUnitWithI:
    sizeUnitListWithI = []
    for curIdx, eachUnit in enumerate(sizeUnitList):
      unitWithI = eachUnit
      if curIdx >= 1:
        unitWithI += 'i'
      sizeUnitListWithI.append(unitWithI)

    # sizeUnitListWithI = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
    sizeUnitList = sizeUnitListWithI

    largestUnit += 'i'

  suffix = "B"
  decimalFormat = "." + str(decimalNum) + "f" # ".1f"
  finalFormat = "%" + decimalFormat + sizeUnitSeperator + "%s%s" # "%.1f%s%s"
  sizeNum = sizeInBytes
  for sizeUnit in sizeUnitList:
      if abs(sizeNum) < 1024.0:
        return finalFormat % (sizeNum, sizeUnit, suffix)
      sizeNum /= 1024.0
  return finalFormat % (sizeNum, largestUnit, suffix)

और उदाहरण आउटपुट है:

def testKb():
  kbSize = 3746
  kbStr = formatSize(kbSize)
  print("%s -> %s" % (kbSize, kbStr))

def testI():
  iSize = 87533
  iStr = formatSize(iSize, isUnitWithI=True)
  print("%s -> %s" % (iSize, iStr))

def testSeparator():
  seperatorSize = 98654
  seperatorStr = formatSize(seperatorSize, sizeUnitSeperator=" ")
  print("%s -> %s" % (seperatorSize, seperatorStr))

def testBytes():
  bytesSize = 352
  bytesStr = formatSize(bytesSize)
  print("%s -> %s" % (bytesSize, bytesStr))

def testMb():
  mbSize = 76383285
  mbStr = formatSize(mbSize, decimalNum=2)
  print("%s -> %s" % (mbSize, mbStr))

def testTb():
  tbSize = 763832854988542
  tbStr = formatSize(tbSize, decimalNum=2)
  print("%s -> %s" % (tbSize, tbStr))

def testPb():
  pbSize = 763832854988542665
  pbStr = formatSize(pbSize, decimalNum=4)
  print("%s -> %s" % (pbSize, pbStr))


def demoFormatSize():
  testKb()
  testI()
  testSeparator()
  testBytes()
  testMb()
  testTb()
  testPb()

  # 3746 -> 3.7KB
  # 87533 -> 85.5KiB
  # 98654 -> 96.3 KB
  # 352 -> 352.0B
  # 76383285 -> 72.84MB
  # 763832854988542 -> 694.70TB
  # 763832854988542665 -> 678.4199PB

0

यह समाधान भी आपसे अपील कर सकता है, यह निर्भर करता है कि आपका मन कैसे काम करता है:

from pathlib import Path    

def get_size(path = Path('.')):
    """ Gets file size, or total directory size """
    if path.is_file():
        size = path.stat().st_size
    elif path.is_dir():
        size = sum(file.stat().st_size for file in path.glob('*.*'))
    return size

def format_size(path, unit="MB"):
    """ Converts integers to common size units used in computing """
    bit_shift = {"B": 0,
            "kb": 7,
            "KB": 10,
            "mb": 17,
            "MB": 20,
            "gb": 27,
            "GB": 30,
            "TB": 40,}
    return "{:,.0f}".format(get_size(path) / float(1 << bit_shift[unit])) + " " + unit

# Tests and test results
>>> get_size("d:\\media\\bags of fun.avi")
'38 MB'
>>> get_size("d:\\media\\bags of fun.avi","KB")
'38,763 KB'
>>> get_size("d:\\media\\bags of fun.avi","kb")
'310,104 kb'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.