Re: PEP 8 exegetics: conditional imports?
On Fri, 07 Aug 2009 16:50:12 +, kj wrote: I seek the wisdom of the elders. Is there a consensus on the matter of conditional imports? Are they righteous? Or are they the way of the wicked? Being an elder doesn't grant you wisdom. It just might mean you've been stupid and ignorant for a long time. For what it's worth, you can take my conditional imports when you've pried them from my cold, dead hands. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
PEP 8 exegetics: conditional imports?
Conditional imports make sense to me, as in the following example: def foobar(filename): if os.path.splitext(filename)[1] == '.gz': import gzip f = gzip.open(filename) else: f = file(filename) # etc. And yet, quoth PEP 8: - Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. ...which seems to condemn conditional imports unequivocally. Then again, the PEP 8 scriptures do not explicitly mention conditional imports at all, as far as I can tell, which leaves open the possibility that they are still righteous. In fact, venerable passages in the Python standard library source code, if properly interpreted, can be seen to carry out conditional imports, such as this fragment recovered from random.py: if a is None: try: a = long(_hexlify(_urandom(16)), 16) except NotImplementedError: import time a = long(time.time() * 256) # use fractional seconds Or even more clearly, this one from test/pystone.py: if __name__ == '__main__': import sys I seek the wisdom of the elders. Is there a consensus on the matter of conditional imports? Are they righteous? Or are they the way of the wicked? kynn -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
On Aug 8, 2:50 am, kj no.em...@please.post wrote: Conditional imports make sense to me, as in the following example[...] And yet, quoth PEP 8: - Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. ...which seems to condemn conditional imports unequivocally. Really? It doesn't mention conditionals at all, it simply says that imports should occur before globals and constants, not before conditions. If you want to put conditions around your imports, then that's the place to do it. I seek the wisdom of the elders. Is there a consensus on the matter of conditional imports? Are they righteous? Or are they the way of the wicked? Bear in mind that PEP 8 primarily applies to submissions to the standard library, in order to provide a standard that aids in understanding them. If a module is used throughout a body of code, it's helpful to list these modules at the top of the code, for clarity. However, if a module is only required under exceptional conditions, you'll often see it imported at the point which it's required: as the import occurs near the code, this mitigates the initial requirement somewhat, and reduces the startup time of the code. The style guide also states: But most importantly: know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask! Checks around imports are often used to provide cross-version compatibility. Embedded imports are often used when the code relying on them is barely used. These are all very common uses. pystone is a good example. Nothing within the modular code of pystone requires sys, it's only imported if the module is executed, primarily for error reporting argument handling. -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
On Fri, 2009-08-07 at 16:50 +, kj wrote: Conditional imports make sense to me, as in the following example: def foobar(filename): if os.path.splitext(filename)[1] == '.gz': import gzip f = gzip.open(filename) else: f = file(filename) # etc. And yet, quoth PEP 8: - Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. ...which seems to condemn conditional imports unequivocally. Then again, the PEP 8 scriptures do not explicitly mention conditional imports at all, as far as I can tell, which leaves open the possibility that they are still righteous. In fact, venerable passages in the Python standard library source code, if properly interpreted, can be seen to carry out conditional imports, such as this fragment recovered from random.py: if a is None: try: a = long(_hexlify(_urandom(16)), 16) except NotImplementedError: import time a = long(time.time() * 256) # use fractional seconds Or even more clearly, this one from test/pystone.py: if __name__ == '__main__': import sys I can't speak for others... but generally you can tell when an import belongs at the top of a module and when you need to make exceptions. I would say that, as a general rule, they go up top (easier to identify what external dependencies a module have). There are, of course, exceptions: * Exceptions and other not-often-executed blocks * Inside test functions (where the imported modules are only used by tests * Inside main() functions where the imported modules are only used if the module is run as a script * When startup-time is important. Often it's necessary to have you module up and running in an instant and import expensive modules as-needed. * Dynamic import such as plugins, etc. Of course, like everything else in PEP 8, it's meant as a guide and not as an order. YMMV. -a -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
On Fri, 2009-08-07 at 16:50 +, kj wrote: Conditional imports make sense to me, as in the following example: def foobar(filename): if os.path.splitext(filename)[1] == '.gz': import gzip f = gzip.open(filename) else: f = file(filename) # etc. I should add that in your example I would probably still put the import at the top, e.g.: import gzip [...] def foobar(filename): if os.path.splitext(filename)[1] == '.gz': f = gzip.open(filename) else: f = open(filename) Reason being is that if later on I decide I want to write another function inside my module that does the same thing I don't have to do the same conditional import. Even better, if this is something you find yourself doing often you can create your own smart open and put it in a library: # file anyfile import __builtin__ import gzip def open(filename, ...): if filename.endswith('.gz'): f = gzip.open(filename, ...) else: f = __builtin__.open(f, ...) return f Then: import anyfile f = anyfile.open(filename, ...) -a -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
kj wrote: Conditional imports make sense to me, as in the following example: def foobar(filename): if os.path.splitext(filename)[1] == '.gz': import gzip f = gzip.open(filename) else: f = file(filename) # etc. And yet, quoth PEP 8: - Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. ...which seems to condemn conditional imports unequivocally. Then again, the PEP 8 scriptures do not explicitly mention conditional imports at all, as far as I can tell, which leaves open the possibility that they are still righteous. In fact, venerable passages in the Python standard library source code, if properly interpreted, can be seen to carry out conditional imports, such as this fragment recovered from random.py: if a is None: try: a = long(_hexlify(_urandom(16)), 16) except NotImplementedError: import time a = long(time.time() * 256) # use fractional seconds Or even more clearly, this one from test/pystone.py: if __name__ == '__main__': import sys I seek the wisdom of the elders. Is there a consensus on the matter of conditional imports? Are they righteous? Or are they the way of the wicked? If you want to take a rational approach measure speed and memory footprint of your program both with the conditional and unconditional imports. Then go with the conditional imports only if you can demonstrate a noticeable benefit. This criterion is unlikely to be met for the examples you give above. time is a built-in module, and gzip a thin wrapper around zlib which is also built-in. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
kj wrote: I seek the wisdom of the elders. Is there a consensus on the matter of conditional imports? Are they righteous? Or are they the way of the wicked? imports in functions are dangerous and may lead to dead locks if they are mixed with threads. An import should never start a thread and you should avoid to import code in threads. Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
Peter Otten __pete...@web.de wrote: This criterion is unlikely to be met for the examples you give above. time is a built-in module, and gzip a thin wrapper around zlib which is also built-in. This is something I was _utterly_ unaware of. Is there a list of what modules are built-in readily available? The only reference[1] I could find via Google doesn't list zlib at all. [1]: http://www.vldb.informatik.hu-berlin.de/Themen/manuals/python/python-texinfo/built-in_modules.html -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
Albert Hopkins wrote: On Fri, 2009-08-07 at 16:50 +, kj wrote: Conditional imports make sense to me, as in the following example: def foobar(filename): if os.path.splitext(filename)[1] == '.gz': import gzip f = gzip.open(filename) else: f = file(filename) # etc. And yet, quoth PEP 8: - Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. ...which seems to condemn conditional imports unequivocally. Then again, the PEP 8 scriptures do not explicitly mention conditional imports at all, as far as I can tell, which leaves open the possibility that they are still righteous. In fact, venerable passages in the Python standard library source code, if properly interpreted, can be seen to carry out conditional imports, such as this fragment recovered from random.py: if a is None: try: a = long(_hexlify(_urandom(16)), 16) except NotImplementedError: import time a = long(time.time() * 256) # use fractional seconds Or even more clearly, this one from test/pystone.py: if __name__ == '__main__': import sys I can't speak for others... but generally you can tell when an import belongs at the top of a module and when you need to make exceptions. I would say that, as a general rule, they go up top (easier to identify what external dependencies a module have). There are, of course, exceptions: * Exceptions and other not-often-executed blocks * Inside test functions (where the imported modules are only used by tests * Inside main() functions where the imported modules are only used if the module is run as a script * When startup-time is important. Often it's necessary to have you module up and running in an instant and import expensive modules as-needed. * Dynamic import such as plugins, etc. Of course, like everything else in PEP 8, it's meant as a guide and not as an order. YMMV. -a Excellent points. I'd add a couple more, one pro, and two con: You need conditionals when you're doing things that are environment-specific. For example, you might use Win32 stuff when on Windows, and something else when on Linux. So you might have a pair of modules which encapsulate the non-portable aspects, and conditionally import one of those. You usually want any imports to be complete before starting multithreading. As somebody else has recently pointed out, there's an import-lock that's active during imports, If two modules do mutual imports (not a good idea, but it is sometimes practically unavoidable), the earlier in the file that the import happens, the less likely for a problem to crop up. So try to put them at the top. -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 8 exegetics: conditional imports?
alex23 wrote: This is something I was _utterly_ unaware of. Is there a list of what modules are built-in readily available? sys.builtin_module_names ('__builtin__', '__main__', '_ast', '_bisect', '_codecs', '_collections', '_functools', '_locale', '_random', '_socket', '_sre', '_struct', '_symtable', '_warnings', '_weakref', 'array', 'binascii', 'cPickle', 'cStringIO', 'errno', 'exceptions', 'fcntl', 'gc', 'grp', 'imp', 'itertools', 'marshal', 'math', 'operator', 'posix', 'pwd', 'select', 'signal', 'spwd', 'strop', 'sys', 'syslog', 'thread', 'time', 'unicodedata', 'xxsubtype', 'zipimport', 'zlib') Peter -- http://mail.python.org/mailman/listinfo/python-list