Live data from Hacker News

Say “no” to import side‐effects in Python

chrismorgan.info

31–40 of 86 posts

Re: Say “no” to import side‐effects in Python

#31

I do most of my work with Perl, rather than Python, but in Perl there are several kinds of stock import-level side-effects which are actually quite helpful. These are pretty light-weight though. They boil down to: 1. Global lexical changes to Perl. Sometimes this is the whole point of an import (for example Carp::Always, which typically turns any warning or exception string into a full stack dump). I can't imagine do…

In Python, side-effects are simply not acceptable at all. One should instead put the code with the side-effect in a function and call it. This is the approach taken by gevent, which allows you to replace the entire I/O stack. But importing it does not effect the change; you must explicitly call code to do that. This is done thus: from gevent.monkey import patch_all patch_all() c.f. http://www.gevent.org/gevent.monkey…

    from __future__ import print_function

Re: Say “no” to import side‐effects in Python

#32

I have the unfortunate "luck" to be using a Python library at work that _loves_ to use import side-effects. Importing it like God intended makes it parse command-line arguments and fail if it doesn't like what was passed in. And that's just the start. Nearly every __init__.py has code in it, including class definitions. I have no idea why.

It's like programmers who find out about metaprogramming. Usually they grow out of it.

Re: Say “no” to import side‐effects in Python

#34
post #31

Earlier quoted context omitted.

In Python, side-effects are simply not acceptable at all. One should instead put the code with the side-effect in a function and call it. This is the approach taken by gevent, which allows you to replace the entire I/O stack. But importing it does not effect the change; you must explicitly call code to do that. This is done thus: from gevent.monkey import patch_all patch_all() c.f. http://www.gevent.org/gevent.monkey…

from __future__ import print_function

That's a side effect, right? Your module after the import is not the same as it was before, or am I missing something?

Re: Say “no” to import side‐effects in Python

#35
post #31

Earlier quoted context omitted.

In Python, side-effects are simply not acceptable at all. One should instead put the code with the side-effect in a function and call it. This is the approach taken by gevent, which allows you to replace the entire I/O stack. But importing it does not effect the change; you must explicitly call code to do that. This is done thus: from gevent.monkey import patch_all patch_all() c.f. http://www.gevent.org/gevent.monkey…

from __future__ import print_function

As I understand it, "from __future__ import ..." statements are actually a special type of statement that doesn't actually import a module at all - they just use similar syntax for compatibility reasons. There is an actual __future__ module, also for compatibility reasons, but importing it has no side-effects.

Re: Say “no” to import side‐effects in Python

#36
post #35
post #31

Earlier quoted context omitted.

from __future__ import print_function

As I understand it, "from __future__ import ..." statements are actually a special type of statement that doesn't actually import a module at all - they just use similar syntax for compatibility reasons. There is an actual __future__ module, also for compatibility reasons, but importing it has no side-effects.

Future statements do import something as well, when run, but their primary purpose is changing the behaviour of the compiler for the current file. They have no behaviour outside of that file, so that is not a publicly visible side-effect.

Re: Say “no” to import side‐effects in Python

#37
post #31

Earlier quoted context omitted.

from __future__ import print_function

That's a side effect, right? Your module after the import is not the same as it was before, or am I missing something?

It only changes the behaviour for the current file, so it's not a side-effect.

Re: Say “no” to import side‐effects in Python

#38

I have the unfortunate "luck" to be using a Python library at work that _loves_ to use import side-effects. Importing it like God intended makes it parse command-line arguments and fail if it doesn't like what was passed in. And that's just the start. Nearly every __init__.py has code in it, including class definitions. I have no idea why.

It's like programmers who find out about metaprogramming. Usually they grow out of it.

I haven't grown out of metaprogramming at all. I just try and use it only when it's the best option. Usually because it means reducing duplication.

I liked metaprogramming to an extent in C++. I _love_ it in D.

Re: Say “no” to import side‐effects in Python

#39
post #10
post #3

Of course you should do this in any language. I once used a Ruby library that, when loaded, would try to connect to a database on a remote machine. Programs which required this library would take several seconds to display their --help output. Because of that and similar incidents, I've learned to import argparse up front but nothing else unless necessary. Once argument parsing is done, then importing other modules b…

> I once used a Ruby library that, when loaded, would try to connect to a database on a remote machine. How is that at all acceptable? I can't believe that a library that phones home would gain any sort of popularity. I can't say I know much of anything about the Ruby community, but if they've conditioned you to jump through hoops like importing modules at specific times to avoid delays, that is a serious problem. Co…

install my module! Also.. trust me because it's totally safe.

curl http://foo.com/tBrwn | bash

http://rvm.io/rvm/install

Re: Say “no” to import side‐effects in Python

#40

Can anyone suggest best practice alternatives to import side-effects?

Keep your heavy runtime code and invocations behind "if __name__ == '__main__'" blocks. Alternately, if you're using a framework keep your runtime code constrained to the appropriate entry class/function. Outside of those blocks, your modules should be mostly constants, functions, and classes.
Post reply on HN