Python相当于~/.bashrc

14
对于那些不熟悉~/.bashrc的人来说,它是一个存在于Unix shell Bash中的可定制脚本。当新终端会话开始时,将运行此特定用户文件。用户可以在该文件中编写常见变量、函数和环境设置,并因此让它们在打开终端窗口时自动加载。
Python 中是否存在类似的东西?本质上,我想在一个脚本中定义一些全局 Python 函数,并确保每当我在计算机上运行 Python 脚本或启动 Python 终端时都会加载它们。我想知道是否已经存在这种行为,或者是否有一种简单明了的方法来实现它。

请查看__init__.py - e0k
5
在每个Python脚本中运行并不是一种受支持的行为(可以使用__init__.py文件来确保在导入一个包或其子级时运行某些代码),但是如果要定制交互式解释器,可以将PYTHONSTARTUP环境变量设置为指向一个包含要在移交给交互式解释器之前运行的Python命令的文件,例如 export PYTHONSTARTUP=$HOME/.pythonrc - ShadowRanger
1
请查看 https://docs.python.org/2/library/site.html。 - Charles Duffy
1
好的,编写所有函数并将其放在/usr/lib/pythonX.y/dist-packages中,在需要时导入它们。简单易行! - Ja8zyjits
@ShadowRanger 这正是我在寻找的。请将其作为答案,我会接受的。 - Jake
3个回答

8

每个Python脚本都运行并不是一个好主意,因为它会破坏命名空间;根据Python之禅

命名空间是一种绝妙的理念 -- 让我们多加利用吧!

话虽如此,__init__.py可用于确保在导入包或其子级时运行某些代码,并且为了自定义交互式解释器,可以将PYTHONSTARTUP环境变量设置为指向在移交给交互式解释器之前要运行的Python命令的文件,例如export PYTHONSTARTUP=$HOME/.pythonrc

只需确保PYTHONSTARTUP文件包含Py2和Py3的合法语法,因为没有PYTHON3STARTUP,它将在两个版本的Python上运行。


例如,此语法 cls = lambda: print("\033c\033[3J", end='') 仅被 Python3 识别。为了避免这种情况,可以执行以下操作:from __future__ import print_function cls = lambda: print("\033c\033[3J", end='') cls() - Mario Palumbo

6
这是个不好的想法——请不要这样做。真的。 (命名空间污染是一个严重的问题,编写只在自己的电脑上工作而无法在其他地方工作的代码对任何人都没有好处。相比之下,如果您把代码打包成一个模块,您可以适当地发布和分发它)。
但是,如果您坚持,请参见site模块,并查看其用户定制行为:
引用: 在此之后,将尝试导入名为usercustomize的模块,如果ENABLE_USER_SITE为true,则该模块可以执行任意用户特定的定制。 这个文件应该在用户site-packages目录中创建(请参阅下文),该目录是sys.path的一部分,除非用-s禁用。 ImportError将被静默忽略。
因此,您可以创建一个usercustomize模块,随心所欲地进行热修补。
作为这种热修补的示例:
def myfunc():
  print 'hello'

main_ns = __import__('__main__')
main_ns.myfunc = myfunc

嗯!如果有一些短小的系统特定函数,比如一些批处理命令,这样还不好吗? - Ja8zyjits
简短回答:是的,不好。"显式优于隐式"是Python编程方式的一部分--如果你正在使用某个本地变量,应该明确表明你正在使用它,而不是隐式地存在于每个命名空间中。 - Charles Duffy
1
如果你只是想要一个本地shell的扩展,也许可以使用IPython及其扩展机制?这样至少不会干扰脚本的行为。请参阅http://ipython.readthedocs.org/en/stable/config/extensions/index.html。 - Charles Duffy
我不清楚这个应该如何工作。例如,我将usercustomize.py添加到/usr/lib/python2.7/dist-packages中,并添加了函数def test_function(): pass。我确保site.ENABLE_USER_SITE == True。但是,调用test_function()会产生一个NameError,表明脚本从未运行。 - Jake
@Jake,仅仅因为它被导入并不意味着它会通过魔法出现在你的默认命名空间中;然而,它确实为你提供了一个平台来进行热修补,这样你就可以(例如)直接进入并修改__main__命名空间(这是交互式shell的默认命名空间)。我已经编辑了一个演示。 - Charles Duffy

6
基本上,我想在脚本中定义一些全局Python函数,并确保每次在我的机器上运行Python脚本或启动Python终端时都会加载它们。
让我们谈谈你的第二个选项。有办法在启动终端时加载函数和变量。我建议使用IPython而不是默认的Python终端。但是,如果不安装IPython,可以修改环境变量PYTHONSTARTUP。但这样会失去分隔配置文件的能力。
一旦安装了IPython,就需要初始化其配置文件。 要创建默认配置文件,请执行以下操作:
ipython profile create 

为了回答其他答案中的共同话题,全局变量和函数是一个坏主意,特别是如果它们是隐式定义的。但是,在启动ipython时,您可以定义和加载单独的配置文件。 要创建这样的配置文件,请执行以下操作:
ipython profile create <name>

加载 <name> 配置文件:

ipython --profile=<name>

现在需要修改配置文件。运行以下命令,查看它们的位置:
ipython locate profile

你应该找到 ipython_config.py 文件。我建议阅读它,里面有非常有用的注释。
但是为了重点,您可以通过将以下行添加到配置文件中,在启动 ipython 时加载任意函数和变量:
c.InteractiveShellApp.exec_lines = [ "def p(s): print s" ]
c.InteractiveShellApp.exec_files = [ "/path/of/script.py" ] 

我正在参考IPython文档ipython_config.py中的注释:

96  # List of files to run at IPython startup.                                      
97  # c.TerminalIPythonApp.exec_files = []                                          
98                                                                                 
99  # lines of code to run at IPython startup.                                      
100 # c.TerminalIPythonApp.exec_lines = []

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接