Hacker News new | past | comments | ask | show | jobs | submit login

Neat but way too magical for my taste. The code to figure out what to do in the case of 'from .. import *' is particularly ugly.

Perhaps the commands should accessible from an object you import. That's slightly more typing but more explicit and would not require ugly magic. E.g.

  from pbs import sh
  print sh.ifconfig('eth')
If it's not clear, the 'sh' object could override __getattr__ or __getattribute__ and wrap commands as necessary.



Anything that encourages a from ... import * usage is evil irrespective of its implementation.


Why?


makes references ambiguous to anyone but the interpreter

let's say you have

from a import foo from b import *

what does 'foo' refer to? 'b' could contain 'foo', which would overwrite your previous reference to 'a.foo'. its hard to figure out what 'foo' now refers to from inspecting the code. its better to be explicit:

from a import foo from b import bar, baz


Because it leads to namespace pollution and hard-to-track-down bugs.

It's especially bad in this case where adding an executable in the system can suddenly shadow any built-in name (e.g. imagine someone adds a "print" or "sys" executable).


Refactoring is also made much harder with import * if you have cascading modules. I have a pylint hook forbidding these before committing to our hg repo


Off the top of my head a) Nothing prevents the writer of the module you are importing from overriding symbols that you expect b) In many cases increased load times. c) Irrelevant symbols present in scope when debugging d) Makes the order of import statements important, because potentially different modules might be providing the same variable name


because this might mess up your script by either overwriting something that's already defined, or you might accidentally overwrite something that is 'hidden' behind the '* '.

somewhat naive example:

    >>> time = 'blah'
    >>> time
    'blah'
    >>> from datetime import *
    >>> time
    <type 'datetime.time'>
    >>>


pollution of the global name space


Irrelevant for shell-style scripts because they are entry points, not included from other modules.

--And its not a "global" name space, its just the namespace of your script.--


It's a global namespace in your script. That's what it's called, I believe and it's available via globals().


Aye, they are added to "current scope's global variables", thank you for correcting.


To avoid any magic you could use:

  ifconfig = pbs.Command("/path/to/ifconfig")




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: