How should we use global variables correctly?

Chris Angelico rosuav at gmail.com
Thu Aug 22 21:33:55 EDT 2019


On Fri, Aug 23, 2019 at 11:24 AM Windson Yang <wiwindson at gmail.com> wrote:
>
> Thank you all for the great explanation, I still trying to find some good
> example to use 'global', In CPython, I found an example use 'global' in
> cpython/Lib/zipfile.py
>
>     _crctable = None
>     def _gen_crc(crc):
>         for j in range(8):
>             if crc & 1:
>                 crc = (crc >> 1) ^ 0xEDB88320
>             else:
>                 crc >>= 1
>         return crc
>
>     def _ZipDecrypter(pwd):
>         key0 = 305419896
>         key1 = 591751049
>         key2 = 878082192
>
>         global _crctable
>         if _crctable is None:
>             _crctable = list(map(_gen_crc, range(256)))
>         crctable = _crctable
>
> _crctable only been used in the _ZipDecrypter function. IIUC, the code can
> be refactored to
>
>     def _gen_crc(crc):
>         ...stay the same
>
>     def _ZipDecrypter(pwd, _crctable=list(map(_gen_crc, range(256)))):
>         key0 = 305419896
>         key1 = 591751049
>         key2 = 878082192
>        crctable = _crctable
>
> Which avoid using 'global' keyword. Why we are not doing this? I guess the
> reason we use 'global' here because we don't want to  create `_crctable =
> list(map(_gen_crc, range(256)))`  every time when we run '_ZipDecrypter'
> function. So we kinda cache _crctable with 'global', am I right?

It's a cache that is made ONLY when it's first needed. If you put it
in the function header, it has to be created eagerly as soon as the
module is imported.

ChrisA



More information about the Python-list mailing list