3
\$\begingroup\$

When I'm writing Python, I wanna be able to pull up an interpreter quickly, and import what I need easily. Previously, this involved:

bash4.3 $ python3
>>> import os, sys, readline, lxml

I was irked by the amount of typing in that, so I wrote a couple of tiny bash functions that live in my .bashrc, so I can just do (for example):

bash4.3 $ from os import path
>>> 
from os import path: success!
>>> 

or:

bash4.3 $ import os, sys, readline, lxml
>>> 
imported os, sys, readline, lxml
>>> 

Perhaps this might be regarded by some as a non-issue, but for my workflow when I just want to test something quickly, it's really handy.

The functions:

function import () {
  ARGS=$*
  ARGS=$(python3 -c "import re;print(', '.join(re.findall(r'([\d\w]+)[, ]*', '$ARGS')))")
  echo -ne '\0x04' | python3 -i
  python3 -c "import $ARGS" &> /dev/null
  if [[ $? != 0 ]]; then
    echo "sorry, junk module in list"
  else
    echo "imported $ARGS"
  fi
  python3 -i -c "import $ARGS"
}

function from () {
  ARGS=$*
  ARGS=$(python3 -c "import re; s = '$ARGS'.replace(',', ', '); args = ' '.join(re.findall(r'^([\d\w]+) import ([\d\w, ]+)$', s)[0]).split(' '); print('from', args[0], 'import', ' '.join(args[1:]).replace(',', '').replace(' ', ','))")
  echo -ne '\0x04' | python3 -i
  python3 -c "$ARGS" &> /dev/null
  if [[ $? != 0 ]]; then
    echo "junk module in list"
  else
    echo "$ARGS: success!"
  fi
  python3 -i -c "$ARGS"
}

I'm aware python3 -m module exists, however, it requires module to be a fully-fledged module, with an __init__.py and stuff. If I'm writing a small script that isn't really designed to be a module (i.e, that has module-level expressions that will be run if the module is imported), then I want to import it normally, not with -m.

I'm also aware I could use && and || for short-circuiting over if [[ ]]; then; fi but I consider this more readable.

I'm looking for responses about any part, really, but I'd be most interested to hear whether I'm unknowingly abusing bash in some way (quoting, perhaps?) and about the probable inefficiency of the Python code I'm using to process / sanitise the args.

I'd also be happy to hear about corner cases not caught by my regex / parsing job, and how they sudo rm -rf --no-preserve-root /-ed you.

\$\endgroup\$
6
  • \$\begingroup\$ Now, why did the Python tag get put ahead of the bash one? :( I put the Python tag second for a reason. \$\endgroup\$
    – cat
    Commented Feb 18, 2016 at 20:16
  • \$\begingroup\$ Have you heard of virtualenv ? Does it not suit you for some reason? \$\endgroup\$
    – janos
    Commented Feb 21, 2016 at 0:06
  • \$\begingroup\$ @janos No, but the last I looked into it, it's more work and time than I need \$\endgroup\$
    – cat
    Commented Feb 21, 2016 at 0:09
  • \$\begingroup\$ @Gao because,i do'nt use ipython :P \$\endgroup\$
    – cat
    Commented Oct 20, 2017 at 23:28
  • \$\begingroup\$ @Gao Well it's helpful, but that runs the same code in the file every time, but I don't always want to import the same modules \$\endgroup\$
    – cat
    Commented Feb 22, 2018 at 22:27

1 Answer 1

1
\$\begingroup\$
  1. Use an alias: alias 3=python3.
  2. Use the PYTHONSTARTUP environment variable: import your most frequently used modules whether or not they'd actually get used in this session.
  3. If you insist on doing it your way, I've made an "improvement" over your code:

    function import
    {
        python3 -ic "import $*"
    }
    
    function from
    {
        args=$*
        python3 -ic "from ${args%import*} import ${args#*import}"
    }
    

    This doesn't guard against anything, nor should you need to.

    Hardened (?) version (use at your own risk):

    function import
    {
        args=$(awk -v q="'" -v ORS=',' '{for(i=1; i<=NF; i++) print q $i q}' <<< "${@/,/ }")
        python3 -ic "for module in eval("\""[$args]"\""): exec(f'import {module}')"
    }
    

Feel free to use any combination of the 3 methods.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.