Pergunta
Eu tenho alguns scripts ipython que têm funcionalidade redundante. Eu gostaria de refazer a funcionalidade comum em um módulo e que incluem módulos no script existente. O problema é que não pode ser feito um módulo python que o código usa extensões de linguagem de ipython (!, $, Etc.). É possível fazer um módulo de ter o código IPython e incluí-lo em outros roteiros ipython?
Solução
Você não deve estar salvando o material extensão IPython (?
, !
, %run
) em arquivos. Sempre. Essas são ferramentas interativas e eles são algo que você digite com as mãos, mas nunca salvar para um arquivo.
-
Encontre as características comuns entre os seus arquivos. Você tem exatamente quatro tipos de coisas que são candidatos para este.
-
Importações (
import
) -
As definições de função (
def
) -
As definições de classe (
class
) -
atribuições de variáveis ??globais
Você deve remover todos os recursos interativos ipython deste código. Tudo isso.
-
-
Reescreva seus scripts para que eles (1) importar seu material comum, (2) fazer o trabalho útil que é suposto fazer.
Você deve remover todos os recursos interativos ipython deste código. Tudo isso.
Agora você pode executar seus scripts e eles são fazer o seu trabalho como scripts Python apropriados são supostos.
Você ainda pode usar recursos de extensão ipython como !
, ?
e %run
quando você está digitando, mas você não deve salvar estes em arquivos.
Outras dicas
tecnicamente se você salvar um script com a extensão .ipy
, ipython vai ver isso e usar toda a sua fantasia coisas ao invés de passar diretamente para o interpretador Python. No entanto, eu geralmente recomendo contra isso, e ir a rota de S.Lott acima.
Muitas pessoas acreditam fortemente que você não é suposto ter scripts com sintaxe IPython neles, mas se você estava curioso o suficiente (como eu) e está procurando algumas maneiras divertidas para misturar scripts python e comandos, deverá check-out a minha invólucro programa no github
Exemplo caso de uso:
$ cat > example.ipy
rehashx
a = !ls -l | tail -n 3
print a.fields(0)
b = 'foo'
echo bar ${b}
$ ipyscript.py example.ipy
['-rw-r--r--', 'drwxr-xr-x', 'drwxrwxr-x']
bar foo
Como se vê, o núcleo IPython também suporta uma versão (mal funcional) do script acima:
In [2]: IPython.core.interactiveshell.InteractiveShell.safe_execfile_ipy?
Type: instancemethod
Base Class: <type 'instancemethod'>
String Form:<unbound method InteractiveShell.safe_execfile_ipy>
Namespace: Interactive
File: /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/core/interactiveshell.py
Definition: IPython.core.interactiveshell.InteractiveShell.safe_execfile_ipy(self, fname)
Docstring:
Like safe_execfile, but for .ipy files with IPython syntax.
Parameters
----------
fname : str
The name of the file to execute. The filename must have a
.ipy extension.
Se você digitar os comandos em uma versão interativa do IPython e, em seguida, use o comando hist (com -n para remover números de linha), IPython cospe todos os comandos que você executou, com o código python real usada no lugar de ! CD! ls, etc. Aqui está um exemplo.
_ip.system("ls")
_ip.system("ls -F ")
_ip.magic("cd ")
http://ipython.scipy.org/moin/IpythonExtensionApi explica este objeto. Este é basicamente o que você precisa fazer (adaptado a partir do link):
import IPython.ipapi
_ip = IPython.ipapi.get()
Agora, todo o código que você colou do comando hist do IPython shell deve funcionar bem.
Você já teve um olhar para o módulo IPython (pydoc IPython
)? talvez você pode acessar utilitários do ipython através de código Python puro.
Você pode fazê-lo.
Aqui está um exemplo.
Este é o conteúdo do arquivo a.ipy:
%run b.ipy
print(myvar)
print(myfunc())
Este é o conteúdo do arquivo b.ipy:
myvar = !echo 1
def myfunc():
tmp_var = !echo 2
return tmp_var
Como você pode ver usos b.ipy! operador. Quando você executa a.ipy você obter o seguinte resultado:
ipython a.ipy
['1']
['2']
Assim, você "importação" "módulos" não como você fazê-lo em python, mas como você fazê-lo em concha com source
.
Mas eu não tenho certeza se é caminho certo, pode ser que é. Pelo menos ele funciona e permite que você extraia funcionalidade comum e reutilizá-lo de outros arquivos de script.