标签归档:command-line

-m开关的作用是什么?

问题:-m开关的作用是什么?

你能给我解释一下打电话之间有什么区别

python -m mymod1 mymod2.py args

python mymod1.py mymod2.py args

看来在这两种情况下mymod1.py被调用,sys.argv

['mymod1.py', 'mymod2.py', 'args']

那么,该-m开关是做什么用的呢?

Could you explain to me what the difference is between calling

python -m mymod1 mymod2.py args

and

python mymod1.py mymod2.py args

It seems in both cases mymod1.py is called and sys.argv is

['mymod1.py', 'mymod2.py', 'args']

So what is the -m switch for?


回答 0

PEP 338Rationale部分的第一行说:

Python 2.4添加了命令行开关-m,以允许使用Python模块命名空间定位模块以作为脚本执行。激励性的示例是标准库模块,例如pdb和profile,并且Python 2.4实现对于此有限的目的是合适的。

因此,您可以通过这种方式在Python的搜索路径中指定任何模块,而不仅仅是当前目录中的文件。您是正确的,python mymod1.py mymod2.py args其效果完全相同。本Scope of this proposal节的第一行指出:

在Python 2.4中,将执行使用-m定位的模块,就像在命令行中提供了其文件名一样。

还有-m更多的可能,例如使用作为包装一部分的模块等,这就是PEP 338其余部分的意义。阅读以获取更多信息。

The first line of the Rationale section of PEP 338 says:

Python 2.4 adds the command line switch -m to allow modules to be located using the Python module namespace for execution as scripts. The motivating examples were standard library modules such as pdb and profile, and the Python 2.4 implementation is fine for this limited purpose.

So you can specify any module in Python’s search path this way, not just files in the current directory. You’re correct that python mymod1.py mymod2.py args has exactly the same effect. The first line of the Scope of this proposal section states:

In Python 2.4, a module located using -m is executed just as if its filename had been provided on the command line.

With -m more is possible, like working with modules which are part of a package, etc. That’s what the rest of PEP 338 is about. Read it for more info.


回答 1

值得一提的是,只有在程序包具有文件的情况下__main__.py,此方法才有效。否则,该程序包无法直接执行。

python -m some_package some_arguments

python解释器将__main__.py在包路径中查找要执行的文件。等效于:

python path_to_package/__main__.py somearguments

它将在以下时间执行内容:

if __name__ == "__main__":

It’s worth mentioning this only works if the package has a file __main__.py Otherwise, this package can not be executed directly.

python -m some_package some_arguments

The python interpreter will looking for a __main__.py file in the package path to execute. It’s equivalent to:

python path_to_package/__main__.py somearguments

It will execute the content after:

if __name__ == "__main__":

回答 2

在我看来,尽管已经多次询问并回答了这个问题(例如,在这里在这里在这里在这里),但是没有一个现有的答案可以完全或简洁地捕捉到该-m标志的所有含义。因此,以下将尝试改进之前的内容。

简介(TLDR)

-m命令执行了很多操作,并非始终需要所有这些命令。简而言之:(1)允许通过模块名而不是文件名执行python脚本(2)允许选择要添加到的目录以sys.path进行import解析,(3)允许从命令行执行具有相对导入的python脚本。

初赛

为了解释-m标志,我们首先必须弄清楚一些术语。

首先,Python的主要组织单位称为模块。模块有两种形式之一:代码模块和包模块。代码模块是包含python可执行代码的任何文件。软件包模块是包含其他模块(代码模块或软件包模块)的目录。代码模块的最常见类型是*.py文件,而软件包模块的最常见类型是包含__init__.py文件的目录。

其次,可以通过两种不同的方式唯一标识所有模块:<modulename><filename>。模块通常由Python代码中的模块名称(例如import <modulename>)和命令行上的文件名(例如)来标识python <filename>。所有Python解释器都可以通过一组定义良好的规则将模块名转换为文件名。这些规则取决于sys.path变量,因此可以通过更改此值来更改映射(有关如何完成此操作的更多信息,请参阅PEP 302)。

第三,所有模块(代码和程序包)都可以执行(这意味着与模块关联的代码将由Python解释器评估)。根据执行方法和模块类型的不同,对哪些代码进行评估以及何时修改可能会有所不同。例如,如果一个人通过执行一个包模块,python <filename>那么<filename>/__init__.py它将被评估,然后是<filename>/__main__.py。另一方面,如果一个人通过执行相同的程序包模块,import <modulename>那么__init__.py将仅执行程序包。

的历史发展 -m

-m标志最初是在Python 2.4.1中引入的。最初,它的唯一目的是提供一种识别要执行的python模块的替代方法。也就是说,如果我们同时知道模块的<filename><modulename>,则以下两个命令是等效的:python <filename> <args>python -m <modulename> <args>。另外,根据PEP 338,此迭代-m仅适用于顶级模块名称(即,可以直接在sys.path上找到的模块,而无需任何中间包)。

随着完成PEP 338-m功能扩展到支持<modulename>超出顶层modulenames表示。这意味着http.server现在已经完全支持诸如这样的名称。此增强功能还意味着模块中的所有软件包现在都已加载(即,所有软件包__init__.py文件均已评估)。

PEP 366-m带来了最终的主要功能增强。通过此更新,不仅可以支持绝对导入,还可以支持显式相对导入。这是通过修改命令中命名模块的变量来实现的。-m__package__-m

用例

-m标志有两种值得注意的用例:

  1. 从命令行执行可能不知道其文件名的模块。该用例利用了Python解释器知道如何将模块名转换为文件名这一事实。当要从命令行运行stdlib模块或第三方模块时,这特别有利。例如,很少有人知道http.server模块的文件名,但大多数人确实知道其模块名,因此我们可以使用从命令行执行它python -m http.server

  2. 要执行包含绝对导入的本地软件包,而无需安装它。PEP 338中详细介绍了该用例,并利用了将当前工作目录添加到sys.path而不是模块目录的事实。该用例与pip install -e .在开发/编辑模式下安装软件包非常相似。

缺点

经过-m多年的改进,它仍然存在一个主要缺点-它只能执行以python编写的代码模块(即* .py)。例如,如果-m用于执行C编译代码模块,则会产生以下错误,No code object available for <modulename>(请参见此处以获取更多详细信息)。

详细比较

通过python命令执行模块的效果(即python <filename>):

  • sys.path 修改为包括最终目录 <filename>
  • __name__ 设定为 '__main__'
  • __package__ 设定为 None
  • __init__.py 不评估任何软件包(包括其自身的软件包模块)
  • __main__.py评估包装模块;对代码进行代码模块评估。

通过import语句(即import <modulename>)执行模块的影响:

  • sys.path以任何方式修改
  • __name__ 设置为的绝对形式 <modulename>
  • __package__ 设置为中的直接父包 <modulename>
  • __init__.py 针对所有软件包进行评估(包括针对软件包模块的评估)
  • __main__.py评价包模块; 对代码进行代码模块评估

通过-m标志(即python -m <modulename>)执行模块的影响:

  • sys.path 修改为包括当前目录
  • __name__ 设定为 '__main__'
  • __package__ 设置为中的直接父包 <modulename>
  • __init__.py 针对所有软件包进行评估(包括针对软件包模块的评估)
  • __main__.py评估包装模块;对代码进行代码模块评估

结论

-m最简单的角度来看,该标志是使用模块名而不是文件名从命令行执行python脚本的一种方法。另外,-m提供了附加功能,结合了import语句的功能(例如,支持显式相对导入和自动包__init__评估)和python命令行的便利性。

Despite this question having been asked and answered several times (e.g., here, here, here, and here) in my opinion no existing answer fully or concisely captures all the implications of the -m flag. Therefore, the following will attempt to improve on what has come before.

Introduction (TLDR)

The -m flag does a lot of things, not all of which will be needed all the time. In short it can be used to: (1) execute python code from the command line via modulename rather than filename (2) add a directory to sys.path for use in import resolution and (3) execute python code that contains relative imports from the command line.

Preliminaries

To explain the -m flag we first need to explain a little terminology.

Python’s primary organizational unit is known as a module. Module’s come in one of two flavors: code modules and package modules. A code module is any file that contains python executable code. A package module is a directory that contains other modules (either code modules or package modules). The most common type of code modules are *.py files while the most common type of package modules are directories containing an __init__.py file.

Python allows modules to be uniquely identified in two distinct ways: modulename and filename. In general, modules are identified by modulename in Python code (e.g., import <modulename>) and by filename on the command line (e.g., python <filename>). All python interpreters are able to convert modulenames to filenames by following the same few, well-defined rules. These rules hinge on the sys.path variable. By altering this variable one can change how Python resolves modulenames into filenames (for more on how this is done see PEP 302).

All modules (both code and package) can be executed (i.e., code associated with the module will be evaluated by the Python interpreter). Depending on the execution method (and module type) what code gets evaluated, and when, can change quite a bit. For example, if one executes a package module via python <filename> then <filename>/__init__.py will be evaluated followed by <filename>/__main__.py. On the other hand, if one executes that same package module via import <modulename> then only the package’s __init__.py will be executed.

Historical Development of -m

The -m flag was first introduced in Python 2.4.1. Initially its only purpose was to provide an alternative means of identifying the python module to execute from the command line. That is, if we knew both the <filename> and <modulename> for a module then the following two commands were equivalent: python <filename> <args> and python -m <modulename> <args>. One constraint with this iteration, according to PEP 338, was that -m only worked with top level modulenames (i.e., modules that could be found directly on sys.path without any intervening package modules).

With the completion of PEP 338 the -m feature was extended to support <modulename> representations beyond the top level. This meant names such as http.server were now fully supported. This extension also meant that each parent package in modulename was now evaluated (i.e., all parent package __init__.py files were evaluated) in addition to the module referenced by the modulename itself.

The final major feature enhancement for -m came with PEP 366. With this upgrade -m gained the ability to support not only absolute imports but also explicit relative imports when executing modules. This was achieved by changing -m so that it set the __package__ variable to the parent module of the given modulename (in addition to everything else it already did).

Use Cases

There are two notable use cases for the -m flag:

  1. To execute modules from the command line for which one may not know their filename. This use case takes advantage of the fact that the Python interpreter knows how to convert modulenames to filenames. This is particularly advantageous when one wants to run stdlib modules or 3rd-party module from the command line. For example, very few people know the filename for the http.server module but most people do know its modulename so we can execute it from the command line using python -m http.server.

  2. To execute a local package containing absolute or relative imports without needing to install it. This use case is detailed in PEP 338 and leverages the fact that the current working directory is added to sys.path rather than the module’s directory. This use case is very similar to using pip install -e . to install a package in develop/edit mode.

Shortcomings

With all the enhancements made to -m over the years it still has one major shortcoming — it can only execute modules written in Python (i.e., *.py). For example, if -m is used to execute a C compiled code module the following error will be produced, No code object available for <modulename> (see here for more details).

Detailed Comparisons

Effects of module execution via import statement (i.e., import <modulename>):

  • sys.path is not modified in any way
  • __name__ is set to the absolute form of <modulename>
  • __package__ is set to the immediate parent package in <modulename>
  • __init__.py is evaluated for all packages (including its own for package modules)
  • __main__.py is not evaluated for package modules; the code is evaluated for code modules

Effects of module execution via command line (i.e., python <filename>):

  • sys.path is modified to include the final directory in <filename>
  • __name__ is set to '__main__'
  • __package__ is set to None
  • __init__.py is not evaluated for any package (including its own for package modules)
  • __main__.py is evaluated for package modules; the code is evaluated for code modules.

Effects of module execution via command line with the -m flag (i.e., python -m <modulename>):

  • sys.path is modified to include the current directory
  • __name__ is set to '__main__'
  • __package__ is set to the immediate parent package in <modulename>
  • __init__.py is evaluated for all packages (including its own for package modules)
  • __main__.py is evaluated for package modules; the code is evaluated for code modules

Conclusion

The -m flag is, at its simplest, a means to execute python scripts from the command line by using modulenames rather than filenames. The real power of -m, however, is in its ability to combine the power of import statements (e.g., support for explicit relative imports and automatic package __init__ evaluation) with the convenience of the command line.


pip install -U中的“ -U”选项代表什么

问题:pip install -U中的“ -U”选项代表什么

尽管有大量Google搜索,但我找不到pip命令行选项/参数的任何文档。什么pip install -U意思 是否有人链接到pip选项和参数列表?

Despite a ton of Googling, I can’t find any docs for pip’s command line options/arguments. What does pip install -U mean? Does anyone have a link to a list of pip’s options and arguments?


回答 0

键入pip install -h列出帮助:

-U,–upgrade将所有软件包升级到最新可用版本

因此,如果您已经安装了软件包,它将为您升级该软件包。如果没有-U开关,它将告诉您该软件包已安装并退出。

每个pip子命令都有其自己的帮助列表。pip -h向您显示总体帮助,并pip [subcommand] -h为该子命令提供帮助,例如install

您也可以在线找到完整的参考文档。“ 常规选项”部分涵盖了每个pip子命令可用的开关,而每个子命令都有一个单独的“ 选项”部分来涵盖特定于子命令的开关;例如,请参阅“ pip install选项”部分

Type pip install -h to list help:

-U, –upgrade Upgrade all packages to the newest available version

So, if you already have a package installed, it will upgrade the package for you. Without the -U switch it’ll tell you the package is already installed and exit.

Each pip subcommand has its own help listing. pip -h shows you overall help, and pip [subcommand] -h gives you help for that sub command, such as install.

You can also find the full reference documentation online; the General Options section covers switches available for every pip subcommand, while each subcommand has a separate Options section to cover subcommand-specific switches; see the pip install options section, for example.


使用argparse获取选定的子命令

问题:使用argparse获取选定的子命令

当我将子命令与python argparse一起使用时,可以获取所选的参数。

parser = argparse.ArgumentParser()
parser.add_argument('-g', '--global')
subparsers = parser.add_subparsers()   
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-c', '--count')
bar_parser = subparsers.add_parser('bar')
args = parser.parse_args(['-g, 'xyz', 'foo', '--count', '42'])
# args => Namespace(global='xyz', count='42')

因此args不包含'foo'sys.argv[1]由于可能存在全局arg,因此简单地编写不起作用。如何获得子命令本身?

When I use subcommands with python argparse, I can get the selected arguments.

parser = argparse.ArgumentParser()
parser.add_argument('-g', '--global')
subparsers = parser.add_subparsers()   
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-c', '--count')
bar_parser = subparsers.add_parser('bar')
args = parser.parse_args(['-g, 'xyz', 'foo', '--count', '42'])
# args => Namespace(global='xyz', count='42')

So args doesn’t contain 'foo'. Simply writing sys.argv[1] doesn’t work because of the possible global args. How can I get the subcommand itself?


回答 0

关于argparse子命令Python文档的最底层介绍了如何执行此操作:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-g', '--global')
>>> subparsers = parser.add_subparsers(dest="subparser_name") # this line changed
>>> foo_parser = subparsers.add_parser('foo')
>>> foo_parser.add_argument('-c', '--count')
>>> bar_parser = subparsers.add_parser('bar')
>>> args = parser.parse_args(['-g', 'xyz', 'foo', '--count', '42'])
>>> args
Namespace(count='42', global='xyz', subparser_name='foo')

您也可以使用set_defaults()我发现的示例上方引用的方法。

The very bottom of the Python docs on argparse sub-commands explains how to do this:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-g', '--global')
>>> subparsers = parser.add_subparsers(dest="subparser_name") # this line changed
>>> foo_parser = subparsers.add_parser('foo')
>>> foo_parser.add_argument('-c', '--count')
>>> bar_parser = subparsers.add_parser('bar')
>>> args = parser.parse_args(['-g', 'xyz', 'foo', '--count', '42'])
>>> args
Namespace(count='42', global='xyz', subparser_name='foo')

You can also use the set_defaults() method referenced just above the example I found.


回答 1

ArgumentParser.add_subparsersdest正式的说法描述为:

dest-将在其下存储子命令名称的属性的名称;默认情况下None,不存储任何值

在以下使用子解析器的简单任务功能布局的示例中,所选子解析器位于中parser.parse_args().subparser

import argparse


def task_a(alpha):
    print('task a', alpha)


def task_b(beta, gamma):
    print('task b', beta, gamma)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='subparser')

    parser_a = subparsers.add_parser('task_a')
    parser_a.add_argument(
        '-a', '--alpha', dest='alpha', help='Alpha description')

    parser_b = subparsers.add_parser('task_b')
    parser_b.add_argument(
        '-b', '--beta', dest='beta', help='Beta description')
    parser_b.add_argument(
        '-g', '--gamma', dest='gamma', default=42, help='Gamma description')

    kwargs = vars(parser.parse_args())
    globals()[kwargs.pop('subparser')](**kwargs)

ArgumentParser.add_subparsers has dest formal argument described as:

dest – name of the attribute under which sub-command name will be stored; by default None and no value is stored

In the example below of a simple task function layout using subparsers, the selected subparser is in parser.parse_args().subparser.

import argparse


def task_a(alpha):
    print('task a', alpha)


def task_b(beta, gamma):
    print('task b', beta, gamma)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='subparser')

    parser_a = subparsers.add_parser('task_a')
    parser_a.add_argument(
        '-a', '--alpha', dest='alpha', help='Alpha description')

    parser_b = subparsers.add_parser('task_b')
    parser_b.add_argument(
        '-b', '--beta', dest='beta', help='Beta description')
    parser_b.add_argument(
        '-g', '--gamma', dest='gamma', default=42, help='Gamma description')

    kwargs = vars(parser.parse_args())
    globals()[kwargs.pop('subparser')](**kwargs)

如何从命令行编译Visual Studio项目?

问题:如何从命令行编译Visual Studio项目?

我正在为使用MonotoneCMake,Visual Studio Express 2008和自定义测试的大型C ++解决方案编写结帐,构建,分发,测试和提交周期的脚本。

所有其他部分似乎都非常简单明了,但是我不明白如何在没有GUI的情况下编译Visual Studio解决方案。

该脚本是用Python编写的,但是给出的答案允许我仅调用os.system。

I’m scripting the checkout, build, distribution, test, and commit cycle for a large C++ solution that is using Monotone, CMake, Visual Studio Express 2008, and custom tests.

All of the other parts seem pretty straight-forward, but I don’t see how to compile the Visual Studio solution without getting the GUI.

The script is written in Python, but an answer that would allow me to just make a call to: os.system would do.


回答 0

我知道有两种方法可以做到。

方法1
第一种方法(我更喜欢)是使用msbuild

msbuild project.sln /Flags...

方法2
您还可以运行:

vcexpress project.sln /build /Flags...

vcexpress选项立即返回,并且不打印任何输出。我想这可能就是您想要的脚本。

请注意,DevEnv并未随Visual Studio Express 2008一起分发(我花了很多时间试图弄清第一次遇到类似问题的时间)。

因此,最终结果可能是:

os.system("msbuild project.sln /p:Configuration=Debug")

您还需要确保您的环境变量正确,因为默认情况下,系统路径上不包含msbuild和vcexpress。启动Visual Studio构建环境并从那里运行脚本,或者修改Python中的路径(使用os.putenv)。

I know of two ways to do it.

Method 1
The first method (which I prefer) is to use msbuild:

msbuild project.sln /Flags...

Method 2
You can also run:

vcexpress project.sln /build /Flags...

The vcexpress option returns immediately and does not print any output. I suppose that might be what you want for a script.

Note that DevEnv is not distributed with Visual Studio Express 2008 (I spent a lot of time trying to figure that out when I first had a similar issue).

So, the end result might be:

os.system("msbuild project.sln /p:Configuration=Debug")

You’ll also want to make sure your environment variables are correct, as msbuild and vcexpress are not by default on the system path. Either start the Visual Studio build environment and run your script from there, or modify the paths in Python (with os.putenv).


回答 1

MSBuild通常可以正常工作,但是我之前遇到过困难。你可能有更好的运气

devenv YourSolution.sln /Build 

MSBuild usually works, but I’ve run into difficulties before. You may have better luck with

devenv YourSolution.sln /Build 

回答 2

老实说,我必须加2美分。

您可以使用msbuild.exe来完成msbuild.exe的版本很多 。

C:\ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ msbuild.exe C:\ Windows \ Microsoft.NET \ Framework64 \ v3.5 \ msbuild.exe C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ msbuild.exe
C:\ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ msbuild.exe C:\ Windows \ Microsoft.NET \ Framework \ v3.5 \ msbuild.exe C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ msbuild.exe

使用您需要的版本。基本上,您必须使用最后一个。

C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ msbuild.exe

那么怎么做。

  1. 运行命令窗口

  2. 输入msbuild.exe的路径

C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ msbuild.exe

  1. 输入项目解决方案的路径,例如

“ C:\ Users \ Clark.Kent \ Documents \ visual studio 2012 \ Projects \ WpfApplication1 \ WpfApplication1.sln”

  1. 在解决方案路径后添加所需的任何标志。

  2. ENTER

请注意,您可以获得有关所有可能标记的帮助,例如

C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ msbuild.exe / help

To be honest I have to add my 2 cents.

You can do it with msbuild.exe. There are many version of the msbuild.exe.

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\msbuild.exe C:\Windows\Microsoft.NET\Framework64\v3.5\msbuild.exe C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe
C:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe

Use version you need. Basically you have to use the last one.

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe

So how to do it.

  1. Run the COMMAND window

  2. Input the path to msbuild.exe

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe

  1. Input the path to the project solution like

“C:\Users\Clark.Kent\Documents\visual studio 2012\Projects\WpfApplication1\WpfApplication1.sln”

  1. Add any flags you need after the solution path.

  2. Press ENTER

Note you can get help about all possible flags like

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /help


回答 3

使用msbuild其他人指出的方法对我有用,但我需要做的不止于此。首先,msbuild需要访问编译器。这可以通过运行以下命令来完成:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"

然后msbuild不在我的$ PATH中,所以我不得不通过它的显式路径运行它:

"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" myproj.sln

最后,我的项目使用了诸如的一些变量$(VisualStudioDir)。看来这些没有被设置,msbuild所以我不得不通过/property选项手动设置它们:

"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" /property:VisualStudioDir="C:\Users\Administrator\Documents\Visual Studio 2013" myproj.sln

那行最终使我能够编译我的项目。

奖励:命令行工具使用30天后似乎不需要注册,就像基于GUI的“免费” Visual Studio Community版本一样。有了Microsoft注册要求,该版本几乎是免费的。如果有的话免费在Facebook上…

Using msbuild as pointed out by others worked for me but I needed to do a bit more than just that. First of all, msbuild needs to have access to the compiler. This can be done by running:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"

Then msbuild was not in my $PATH so I had to run it via its explicit path:

"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" myproj.sln

Lastly, my project was making use of some variables like $(VisualStudioDir). It seems those do not get set by msbuild so I had to set them manually via the /property option:

"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" /property:VisualStudioDir="C:\Users\Administrator\Documents\Visual Studio 2013" myproj.sln

That line then finally allowed me to compile my project.

Bonus: it seems that the command line tools do not require a registration after 30 days of using them like the “free” GUI-based Visual Studio Community edition does. With the Microsoft registration requirement in place, that version is hardly free. Free-as-in-facebook if anything…


回答 4

MSBuild是您的朋友。

msbuild "C:\path to solution\project.sln"

MSBuild is your friend.

msbuild "C:\path to solution\project.sln"

回答 5

DEVENV在许多情况下都能很好地工作,但是在WIXPROJ上构建我的WIX安装程序时,我得到的只是Out日志中的“ CATASTROPHIC”错误。

这有效:MSBUILD /Path/PROJECT.WIXPROJ / t:Build / p:Configuration =发布

DEVENV works well in many cases, but on a WIXPROJ to build my WIX installer, all I got is “CATASTROPHIC” error in the Out log.

This works: MSBUILD /Path/PROJECT.WIXPROJ /t:Build /p:Configuration=Release


如何从IDLE交互式shell运行python脚本?

问题:如何从IDLE交互式shell运行python脚本?

如何从IDLE交互式外壳程序中运行python脚本?

以下引发错误:

>>> python helloworld.py
SyntaxError: invalid syntax

How do I run a python script from within the IDLE interactive shell?

The following throws an error:

>>> python helloworld.py
SyntaxError: invalid syntax

回答 0

Python3

exec(open('helloworld.py').read())

如果您的文件不在同一目录中:

exec(open('./app/filename.py').read())

有关传递全局/局部变量的信息,请参阅https://stackoverflow.com/a/437857/739577


在不推荐使用的Python版本中

Python2 内置函数:execfile

execfile('helloworld.py')

通常不能用参数调用它。但是,有一个解决方法:

import sys
sys.argv = ['helloworld.py', 'arg']  # argv[0] should still be the script name
execfile('helloworld.py')

从2.6开始不推荐使用:popen

import os
os.popen('python helloworld.py') # Just run the program
os.popen('python helloworld.py').read() # Also gets you the stdout

带参数:

os.popen('python helloworld.py arg').read()

预先使用:子流程

import subprocess
subprocess.call(['python', 'helloworld.py']) # Just run the program
subprocess.check_output(['python', 'helloworld.py']) # Also gets you the stdout

带参数:

subprocess.call(['python', 'helloworld.py', 'arg'])

阅读文档以获取详细信息:-)


用这个基础测试helloworld.py

import sys
if len(sys.argv) > 1:
    print(sys.argv[1])

Python3:

exec(open('helloworld.py').read())

If your file not in the same dir:

exec(open('./app/filename.py').read())

See https://stackoverflow.com/a/437857/739577 for passing global/local variables.


In deprecated Python versions

Python2 Built-in function: execfile

execfile('helloworld.py')

It normally cannot be called with arguments. But here’s a workaround:

import sys
sys.argv = ['helloworld.py', 'arg']  # argv[0] should still be the script name
execfile('helloworld.py')

Deprecated since 2.6: popen

import os
os.popen('python helloworld.py') # Just run the program
os.popen('python helloworld.py').read() # Also gets you the stdout

With arguments:

os.popen('python helloworld.py arg').read()

Advance usage: subprocess

import subprocess
subprocess.call(['python', 'helloworld.py']) # Just run the program
subprocess.check_output(['python', 'helloworld.py']) # Also gets you the stdout

With arguments:

subprocess.call(['python', 'helloworld.py', 'arg'])

Read the docs for details :-)


Tested with this basic helloworld.py:

import sys
if len(sys.argv) > 1:
    print(sys.argv[1])

回答 1

您可以在python3中使用它:

exec(open(filename).read())

You can use this in python3:

exec(open(filename).read())

回答 2

空闲外壳窗口与终端外壳(例如,运行shbash)不同。而是就像在Python交互式解释器(python -i)中一样。在IDLE中运行脚本的最简单方法是使用菜单中的Open命令File(这可能会有所不同,具体取决于运行的平台),将脚本文件加载到IDLE编辑器窗口中,然后使用Run-> Run Module命令(快捷方式F5)。

The IDLE shell window is not the same as a terminal shell (e.g. running sh or bash). Rather, it is just like being in the Python interactive interpreter (python -i). The easiest way to run a script in IDLE is to use the Open command from the File menu (this may vary a bit depending on which platform you are running) to load your script file into an IDLE editor window and then use the Run -> Run Module command (shortcut F5).


回答 3

试试这个

import os
import subprocess

DIR = os.path.join('C:\\', 'Users', 'Sergey', 'Desktop', 'helloword.py')

subprocess.call(['python', DIR])

Try this

import os
import subprocess

DIR = os.path.join('C:\\', 'Users', 'Sergey', 'Desktop', 'helloword.py')

subprocess.call(['python', DIR])

回答 4

execFile('helloworld.py')为我做这份工作。需要注意的是,如果.py文件不在Python文件夹本身中,请输入.py文件的完整目录名称(至少在Windows中是这种情况)

例如, execFile('C:/helloworld.py')

execFile('helloworld.py') does the job for me. A thing to note is to enter the complete directory name of the .py file if it isnt in the Python folder itself (atleast this is the case on Windows)

For example, execFile('C:/helloworld.py')


回答 5

最简单的方法

python -i helloworld.py  #Python 2

python3 -i helloworld.py #Python 3

EASIEST WAY

python -i helloworld.py  #Python 2

python3 -i helloworld.py #Python 3

回答 6

例如:

import subprocess

subprocess.call("C:\helloworld.py")

subprocess.call(["python", "-h"])

For example:

import subprocess

subprocess.call("C:\helloworld.py")

subprocess.call(["python", "-h"])

回答 7

在Python 3中,没有execFile。一个可以使用exec内置函数,例如:

import helloworld
exec('helloworld')

In Python 3, there is no execFile. One can use exec built-in function, for instance:

import helloworld
exec('helloworld')

回答 8

在IDLE中,以下工作:

import helloworld

我对它为什么起作用并不十分了解,但是它确实起作用。

In IDLE, the following works :-

import helloworld

I don’t know much about why it works, but it does..


回答 9

要在python外壳程序(例如Idle)或Django外壳程序中运行python脚本,您可以使用exec()函数执行以下操作。Exec()执行代码对象参数。Python中的代码对象就是简单地编译的Python代码。因此,您必须首先编译脚本文件,然后使用exec()执行它。从您的外壳:

>>>file_to_compile = open('/path/to/your/file.py').read()
>>>code_object = compile(file_to_compile, '<string>', 'exec')
>>>exec(code_object)

我正在使用Python 3.4。有关详细信息,请参见compileexec文档。

To run a python script in a python shell such as Idle or in a Django shell you can do the following using the exec() function. Exec() executes a code object argument. A code object in Python is simply compiled Python code. So you must first compile your script file and then execute it using exec(). From your shell:

>>>file_to_compile = open('/path/to/your/file.py').read()
>>>code_object = compile(file_to_compile, '<string>', 'exec')
>>>exec(code_object)

I’m using Python 3.4. See the compile and exec docs for detailed info.


回答 10

我对此进行了测试,并且可以解决:

exec(open('filename').read())  # Don't forget to put the filename between ' '

I tested this and it kinda works out :

exec(open('filename').read())  # Don't forget to put the filename between ' '

回答 11

你可以通过两种方式做到

  • import file_name

  • exec(open('file_name').read())

但请确保该文件应存储在程序运行的位置

you can do it by two ways

  • import file_name

  • exec(open('file_name').read())

but make sure that file should be stored where your program is running


回答 12

在Windows环境中,您可以使用以下语法在Python3 Shell命令行上执行py文件:

exec(open(’file_name的绝对路径’).read())

下面说明了如何从python shell命令行执行简单的helloworld.py文件

文件位置:C:/Users/testuser/testfolder/helloworld.py

文件内容:print(“ hello world”)

我们可以在Python3.7 Shell上执行以下文件:

>>> import os
>>> abs_path = 'C://Users/testuser/testfolder'
>>> os.chdir(abs_path)
>>> os.getcwd()
'C:\\Users\\testuser\\testfolder'

>>> exec(open("helloworld.py").read())
hello world

>>> exec(open("C:\\Users\\testuser\\testfolder\\helloworld.py").read())
hello world

>>> os.path.abspath("helloworld.py")
'C:\\Users\\testuser\\testfolder\\helloworld.py'
>>> import helloworld
hello world

On Windows environment, you can execute py file on Python3 shell command line with the following syntax:

exec(open(‘absolute path to file_name’).read())

Below explains how to execute a simple helloworld.py file from python shell command line

File Location: C:/Users/testuser/testfolder/helloworld.py

File Content: print(“hello world”)

We can execute this file on Python3.7 Shell as below:

>>> import os
>>> abs_path = 'C://Users/testuser/testfolder'
>>> os.chdir(abs_path)
>>> os.getcwd()
'C:\\Users\\testuser\\testfolder'

>>> exec(open("helloworld.py").read())
hello world

>>> exec(open("C:\\Users\\testuser\\testfolder\\helloworld.py").read())
hello world

>>> os.path.abspath("helloworld.py")
'C:\\Users\\testuser\\testfolder\\helloworld.py'
>>> import helloworld
hello world

回答 13

还有另一种选择(适用于Windows)-

    import os
    os.system('py "<path of program with extension>"')

There is one more alternative (for windows) –

    import os
    os.system('py "<path of program with extension>"')

回答 14

在python控制台中,可以尝试以下2种方法。

在同一个工作目录下

1. >>导入helloworld

#如果您有变量x,则可以在IDLE中将其打印出来。

>> helloworld.x

#如果您具有函数func,则也可以这样调用它。

>> helloworld.func()

2. >> runfile(“ ./ helloworld.py”)

In a python console, one can try the following 2 ways.

under the same work directory,

1. >> import helloworld

# if you have a variable x, you can print it in the IDLE.

>> helloworld.x

# if you have a function func, you can also call it like this.

>> helloworld.func()

2. >> runfile(“./helloworld.py”)


如何在Python中美化JSON?

问题:如何在Python中美化JSON?

有人可以建议我如何使用Python或通过命令行美化JSON吗?

唯一可以做到的基于在线的JSON美化器是:http : //jsonviewer.stack.hu/

但是,我需要在Python中使用它。

这是我的数据集:

{ "head": {"vars": [ "address" , "description" ,"listprice" ]} , "results": { "bindings": [ 
    {
        "address" : { "type":"string", "value" : " Dyne Road, London NW6"},
            "description" :{ "type":"string", "value" : "6 bed semi detached house"},
            "listprice" : { "type":"string", "value" : "1,150,000"}
    }
    ,
        {
            "address" : { "type":"string", "value" : " Tweedy Road, Bromley BR1"},
            "description" :{ "type":"string", "value" : "5 bed terraced house"},
            "listprice" : { "type":"string", "value" : "550,000"}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Vera Avenue, London N21"},
            "description" :{ "type":"string", "value" : "4 bed detached house"},
            "listprice" : { "type":"string", "value" : "

                995,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Wimbledon Park Side, London SW19"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Westbere Road, West Hampstead, London NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Avenue, Hatch End, Pinner HA5"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Princes Park Avenue, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Canons Drive, Edgware HA8"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Westbere Road, West Hampstead NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Haymills Estate, Ealing, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Northwick Close, St John's Wood NW8"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Claremont Gardens, Surbiton KT6"},
            "description" :{ "type":"string", "value" : "13 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  end terrace house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stamford Road, London N1"},
            "description" :{ "type":"string", "value" : "4 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, London N3"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Haymills Estate, Ealing, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Elms Crescent, London SW4"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Princes Park Avenue, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Abbeville Road, London SW4"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Canons Drive, Edgware HA8"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Henson Avenue, Willesdon Green NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodstock Road, London NW11"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Tamworth Street, London SW6"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, Finchley, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Old Burlington, Church Street, London W4"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ebury Close, Northwood HA6"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Middleton Road, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Henson Avenue, Willesden Green NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Huron Road, London SW17"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Corringway, Ealing W5"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodlands Avenue, New Malden KT3"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Gunnersbury Park Area, Ealing, London"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Blenheim Gardens, London, Brent NW2"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Creighton Road, London NW6"},
            "description" :{ "type":"string", "value" : "4 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Plaistow Lane, Bromley BR1"},
            "description" :{ "type":"string", "value" : "7 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Greenfield Gardens, London NW2"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Hendon Avenue, London N3"},
            "description" :{ "type":"string", "value" : "3 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Peckham Park Road, London SE15"},
            "description" :{ "type":"string", "value" : "6 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodclyffe Drive, Chislehurst BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  house for sale"},
            "listprice" : { "type":"string", "value" : "

                From 1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Highwood Hill, Mill Hill, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, London N3"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Kersley Mews, London SW11"},
            "description" :{ "type":"string", "value" : "3 bedroom  mews for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ebury Close, Northwood HA6"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ellesmere Road, Chiswick W4"},
            "description" :{ "type":"string", "value" : "6 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Avenue, Hatch End, Pinner, Middlesex"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Wandsworth, London SW18"},
            "description" :{ "type":"string", "value" : "6 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Carlton Road, New Malden KT3"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " St Mary's Mews, Ealing W5"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ritherdon Road, Balham, London SW17"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Goldsmith Avenue, London W3"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Plaistow Lane, Bromley, Kent BR1"},
            "description" :{ "type":"string", "value" : "7 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ] } }

Can someone suggest how I can beautify JSON in Python or through the command line?

The only online based JSON beautifier which could do it was: http://jsonviewer.stack.hu/.

I need to use it from within Python, however.

This is my dataset:

{ "head": {"vars": [ "address" , "description" ,"listprice" ]} , "results": { "bindings": [ 
    {
        "address" : { "type":"string", "value" : " Dyne Road, London NW6"},
            "description" :{ "type":"string", "value" : "6 bed semi detached house"},
            "listprice" : { "type":"string", "value" : "1,150,000"}
    }
    ,
        {
            "address" : { "type":"string", "value" : " Tweedy Road, Bromley BR1"},
            "description" :{ "type":"string", "value" : "5 bed terraced house"},
            "listprice" : { "type":"string", "value" : "550,000"}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Vera Avenue, London N21"},
            "description" :{ "type":"string", "value" : "4 bed detached house"},
            "listprice" : { "type":"string", "value" : "

                995,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Wimbledon Park Side, London SW19"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Westbere Road, West Hampstead, London NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Avenue, Hatch End, Pinner HA5"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Princes Park Avenue, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Canons Drive, Edgware HA8"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Westbere Road, West Hampstead NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Haymills Estate, Ealing, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Northwick Close, St John's Wood NW8"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Claremont Gardens, Surbiton KT6"},
            "description" :{ "type":"string", "value" : "13 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Dene Terrace Woodclyffe Drive, Chislehurst, Kent BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  end terrace house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stamford Road, London N1"},
            "description" :{ "type":"string", "value" : "4 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, London N3"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Haymills Estate, Ealing, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Elms Crescent, London SW4"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Princes Park Avenue, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Abbeville Road, London SW4"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Canons Drive, Edgware HA8"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Henson Avenue, Willesdon Green NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodstock Road, London NW11"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Tamworth Street, London SW6"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, Finchley, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Old Burlington, Church Street, London W4"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ebury Close, Northwood HA6"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Middleton Road, London NW11"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Henson Avenue, Willesden Green NW2"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Huron Road, London SW17"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Corringway, Ealing W5"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodlands Avenue, New Malden KT3"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Gunnersbury Park Area, Ealing, London"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Blenheim Gardens, London, Brent NW2"},
            "description" :{ "type":"string", "value" : "6 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Creighton Road, London NW6"},
            "description" :{ "type":"string", "value" : "4 bedroom  terraced house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Plaistow Lane, Bromley BR1"},
            "description" :{ "type":"string", "value" : "7 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Greenfield Gardens, London NW2"},
            "description" :{ "type":"string", "value" : "4 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Hendon Avenue, London N3"},
            "description" :{ "type":"string", "value" : "3 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Peckham Park Road, London SE15"},
            "description" :{ "type":"string", "value" : "6 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Woodclyffe Drive, Chislehurst BR7"},
            "description" :{ "type":"string", "value" : "5 bedroom  house for sale"},
            "listprice" : { "type":"string", "value" : "

                From 1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Highwood Hill, Mill Hill, London"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Stanhope Avenue, London N3"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Kersley Mews, London SW11"},
            "description" :{ "type":"string", "value" : "3 bedroom  mews for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ebury Close, Northwood HA6"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ellesmere Road, Chiswick W4"},
            "description" :{ "type":"string", "value" : "6 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " The Avenue, Hatch End, Pinner, Middlesex"},
            "description" :{ "type":"string", "value" : "5 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Wandsworth, London SW18"},
            "description" :{ "type":"string", "value" : "6 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Carlton Road, New Malden KT3"},
            "description" :{ "type":"string", "value" : "4 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " St Mary's Mews, Ealing W5"},
            "description" :{ "type":"string", "value" : "3 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Ritherdon Road, Balham, London SW17"},
            "description" :{ "type":"string", "value" : "5 bedroom  semi detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Goldsmith Avenue, London W3"},
            "description" :{ "type":"string", "value" : "5 bedroom  property for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ,
        {
            "address" : { "type":"string", "value" : " Plaistow Lane, Bromley, Kent BR1"},
            "description" :{ "type":"string", "value" : "7 bedroom  detached house for sale"},
            "listprice" : { "type":"string", "value" : "

                1,250,000


                    "}
        }
    ] } }

回答 0

在命令行中:

echo '{"one":1,"two":2}' | python -mjson.tool

输出:

{
    "one": 1, 
    "two": 2
}

Python手册以编程方式描述了精美印刷的JSON

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

From the command-line:

echo '{"one":1,"two":2}' | python -mjson.tool

which outputs:

{
    "one": 1, 
    "two": 2
}

Programmtically, the Python manual describes pretty-printing JSON:

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

回答 1

json模块中使用函数的indent参数。dumps

从文档:

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

Use the indent argument of the dumps function in the json module.

From the docs:

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
    "4": 5,
    "6": 7
}

回答 2

一个最小的Python内解决方案,该解决方案为通过命令行提供的json数据着色:

import sys
import json
from pygments import highlight, lexers, formatters

formatted_json = json.dumps(json.loads(sys.argv[1]), indent=4)
colorful_json = highlight(unicode(formatted_json, 'UTF-8'), lexers.JsonLexer(), formatters.TerminalFormatter())
print(colorful_json)

pjson上述启发。该代码需要pygments安装。

输出示例:

A minimal in-python solution that colors json data supplied via the command line:

import sys
import json
from pygments import highlight, lexers, formatters

formatted_json = json.dumps(json.loads(sys.argv[1]), indent=4)
colorful_json = highlight(unicode(formatted_json, 'UTF-8'), lexers.JsonLexer(), formatters.TerminalFormatter())
print(colorful_json)

Inspired by pjson mentioned above. This code needs pygments to be installed.

Output example:


回答 3

试试underscore-cli

cat myfile.json | underscore print --color

这是一个非常漂亮的工具,可以优雅地对结构化数据进行大量操作,执行js代码片段,填充模板等。它具有荒谬的文档记录,完善的结构,可供认真使用。我写的。:)

Try underscore-cli:

cat myfile.json | underscore print --color

It’s a pretty nifty tool that can elegantly do a lot of manipulation of structured data, execute js snippets, fill templates, etc. It’s ridiculously well documented, polished, and ready for serious use. And I wrote it. :)


回答 4

我为此使用python的cli命令是:

cat myfile.json | python -mjson.tool

您应该可以在这里找到更多信息:

http://docs.python.org/library/json.html

The cli command I’ve used with python for this is:

cat myfile.json | python -mjson.tool

You should be able to find more info here:

http://docs.python.org/library/json.html


回答 5

看起来jsbeautifier开源了他们的工具,并将它们打包为Python和JS库以及CLI工具。看起来他们并不喜欢Web服务,但我并没有仔细检查。请参阅带有安装说明的github repo


从他们的文档中了解Python CLI和库的用法:

要使用python进行美化:

$ pip install jsbeautifier
$ js-beautify file.js

美化的输出到 stdout

要使用jsbeautifier作为一个库很简单:

import jsbeautifier
res = jsbeautifier.beautify('your javascript string')
res = jsbeautifier.beautify_file('some_file.js')

…或指定一些选项:

opts = jsbeautifier.default_options()
opts.indent_size = 2
res = jsbeautifier.beautify('some javascript', opts)

如果要传递字符串而不是文件名,并且正在使用bash,则可以使用进程替换,如下所示:

$ js-beautify <(echo '{"some": "json"}')

It looks like jsbeautifier open sourced their tools and packaged them as Python and JS libs, and as CLI tools. It doesn’t look like they call out to a web service, but I didn’t check too closely. See the github repo with install instructions.


From their docs for Python CLI and library usage:

To beautify using python:

$ pip install jsbeautifier
$ js-beautify file.js

Beautified output goes to stdout.

To use jsbeautifier as a library is simple:

import jsbeautifier
res = jsbeautifier.beautify('your javascript string')
res = jsbeautifier.beautify_file('some_file.js')

…or, to specify some options:

opts = jsbeautifier.default_options()
opts.indent_size = 2
res = jsbeautifier.beautify('some javascript', opts)

If you want to pass a string instead of a filename, and you are using bash, then you can use process substitution like so:

$ js-beautify <(echo '{"some": "json"}')

回答 6

我不喜欢json.dumps(…)->的输出,因为我的口味太多了换行符。而且我不想使用命令行工具或安装某些工具。我终于找到了Pythons pprint(=漂亮打印)。不幸的是,它不会生成正确的JSON,但我认为对存储的数据使用用户友好的glympse很有用。

输出 json.dumps(json_dict, indent=4)

{
    "hyperspace": {
        "constraints": [],
        "design": [
            [
                "windFarm.windparkSize.k",
                "continuous",
                [
                    0,
                    0,
                    5
                ]
            ],
            [
                "hydroPlant.primaryControlMax",
                "continuous",
                [
                    100,
                    300
                ]
            ]
        ],
        "kpis": [
            "frequency.y",
            "city.load.p[2]"
        ]
    },
    "lhc_size": 10,
    "number_of_runs": 10
}

pprint的用法:

import pprint

json_dict = {"hyperspace": {"constraints": [], "design": [["windFarm.windparkSize.k", "continuous", [0, 0, 5]], ["hydroPlant.primaryControlMax", "continuous", [100, 300]]], "kpis": ["frequency.y", "city.load.p[2]"]}, "lhc_size": 10, "number_of_runs": 10}

formatted_json_str = pprint.pformat(json_dict)
print(formatted_json_str)
pprint.pprint(json_dict)

pprint.pformat(...)或的结果pprint.pprint(...)

{'hyperspace': {'constraints': [],
                'design': [['windFarm.windparkSize.k', 'continuous', [0, 0, 5]],
                           ['hydroPlant.primaryControlMax',
                            'continuous',
                            [100, 300]]],
                'kpis': ['frequency.y', 'city.load.p[2]']},
 'lhc_size': 10,
 'number_of_runs': 10}

I didn’t like the output of json.dumps(…) -> For my taste way too much newlines. And I didn’t want to use a command line tool or install something. I finally found Pythons pprint (= pretty print). Unfortunately it doesn’t generate proper JSON but I think it is useful to have a user friendly glympse at the stored data.

Output of json.dumps(json_dict, indent=4)

{
    "hyperspace": {
        "constraints": [],
        "design": [
            [
                "windFarm.windparkSize.k",
                "continuous",
                [
                    0,
                    0,
                    5
                ]
            ],
            [
                "hydroPlant.primaryControlMax",
                "continuous",
                [
                    100,
                    300
                ]
            ]
        ],
        "kpis": [
            "frequency.y",
            "city.load.p[2]"
        ]
    },
    "lhc_size": 10,
    "number_of_runs": 10
}

Usage of pprint:

import pprint

json_dict = {"hyperspace": {"constraints": [], "design": [["windFarm.windparkSize.k", "continuous", [0, 0, 5]], ["hydroPlant.primaryControlMax", "continuous", [100, 300]]], "kpis": ["frequency.y", "city.load.p[2]"]}, "lhc_size": 10, "number_of_runs": 10}

formatted_json_str = pprint.pformat(json_dict)
print(formatted_json_str)
pprint.pprint(json_dict)

Result of pprint.pformat(...) or pprint.pprint(...):

{'hyperspace': {'constraints': [],
                'design': [['windFarm.windparkSize.k', 'continuous', [0, 0, 5]],
                           ['hydroPlant.primaryControlMax',
                            'continuous',
                            [100, 300]]],
                'kpis': ['frequency.y', 'city.load.p[2]']},
 'lhc_size': 10,
 'number_of_runs': 10}

回答 7

alias jsonp='pbpaste | python -m json.tool'

这将漂亮地打印OSX中剪贴板上的JSON。只需复制它,然后在Bash提示符下调用别名即可。

alias jsonp='pbpaste | python -m json.tool'

This will pretty print JSON that’s on the clipboard in OSX. Just Copy it then call the alias from a Bash prompt.


回答 8

您可以将输出传递给jq。如果您的python脚本包含类似

print json.dumps(data)

然后您可以开火:

python foo.py | jq '.'

You could pipe the output to jq. If you python script contains something like

print json.dumps(data)

then you can fire:

python foo.py | jq '.'

回答 9

使用python工具库

命令行:python -mjson.tool

在代码中:http : //docs.python.org/library/json.html

Use the python tool library

Command line: python -mjson.tool

In code: http://docs.python.org/library/json.html


回答 10

首次安装pygments

然后

echo '<some json>' | python -m json.tool | pygmentize -l json

First install pygments

then

echo '<some json>' | python -m json.tool | pygmentize -l json


回答 11

您的数据格式不正确。值字段尤其具有许多空格和换行符。自动格式化程序将无法解决此问题,因为它们不会修改实际数据。生成用于输出的数据时,请根据需要对其进行过滤以避免空格。

Your data is poorly formed. The value fields in particular have numerous spaces and new lines. Automated formatters won’t work on this, as they will not modify the actual data. As you generate the data for output, filter it as needed to avoid the spaces.


回答 12

使用jsonlint(例如xmllint):

aptitude install python-demjson
jsonlint -f foo.json

With jsonlint (like xmllint):

aptitude install python-demjson
jsonlint -f foo.json

在单行命令行中执行多行语句?

问题:在单行命令行中执行多行语句?

我正在使用Python -c执行单线循环,即:

$ python -c "for r in range(10): print 'rob'"

这很好。但是,如果在for循环之前导入模块,则会出现语法错误:

$ python -c "import sys; for r in range(10): print 'rob'"
  File "<string>", line 1
    import sys; for r in range(10): print 'rob'
              ^
SyntaxError: invalid syntax

任何想法如何解决?

对我而言,将其作为一个单行放置非常重要,这样我才能将其包含在Makefile中。

I’m using Python with -c to execute a one-liner loop, i.e.:

$ python -c "for r in range(10): print 'rob'"

This works fine. However, if I import a module before the for loop, I get a syntax error:

$ python -c "import sys; for r in range(10): print 'rob'"
  File "<string>", line 1
    import sys; for r in range(10): print 'rob'
              ^
SyntaxError: invalid syntax

Any idea how this can be fixed?

It’s important to me to have this as a one-liner so that I can include it in a Makefile.


回答 0

你可以做

echo -e "import sys\nfor r in range(10): print 'rob'" | python

或不带管道:

python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"

要么

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

或@ SilentGhost的答案 / @ Crast的答案

you could do

echo -e "import sys\nfor r in range(10): print 'rob'" | python

or w/out pipes:

python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"

or

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

or @SilentGhost’s answer / @Crast’s answer


回答 1

这种样式也可以在makefile中使用(实际上,它经常使用)。

python - <<EOF
import sys
for r in range(3): print 'rob'
EOF

要么

python - <<-EOF
    import sys
    for r in range(3): print 'rob'
EOF

在后一种情况下,也删除了前导制表符(并且可以实现某些结构化的外观)

代替EOF可以忍受行首未出现在here文档中的任何标记词(另请参见bash联机帮助页中的here文档或here)。

this style can be used in makefiles too (and in fact it is used quite often).

python - <<EOF
import sys
for r in range(3): print 'rob'
EOF

or

python - <<-EOF
    import sys
    for r in range(3): print 'rob'
EOF

in latter case leading tab characters are removed too (and some structured outlook can be achieved)

instead of EOF can stand any marker word not appearing in the here document at a beginning of a line (see also here documents in the bash manpage or here).


回答 2

问题实际上与import语句无关,而是for循环之前的所有内容。更具体地说,任何在内联块之前出现的内容。

例如,所有这些工作:

python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"

如果将import声明为问题,则可以这样做,但不能:

python -c "__import__('sys'); for r in range(10): print 'rob'"

对于非常基本的示例,可以将其重写为:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

但是,lambda只能执行表达式,而不能执行语句或多个语句,因此您可能仍然无法执行想要执行的操作。但是,在生成器表达式,列表推导,lambda,sys.stdout.write,内置的“ map”以及一些创造性的字符串插值之间,您可以执行一些强大的单线操作。

问题是,您想走多远?在什么时候写一个.py由makefile执行的小文件更好?

The issue is not actually with the import statement, it’s with anything being before the for loop. Or more specifically, anything appearing before an inlined block.

For example, these all work:

python -c "import sys; print 'rob'"
python -c "import sys; sys.stdout.write('rob\n')"

If import being a statement were an issue, this would work, but it doesn’t:

python -c "__import__('sys'); for r in range(10): print 'rob'"

For your very basic example, you could rewrite it as this:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

However, lambdas can only execute expressions, not statements or multiple statements, so you may still be unable to do the thing you want to do. However, between generator expressions, list comprehension, lambdas, sys.stdout.write, the “map” builtin, and some creative string interpolation, you can do some powerful one-liners.

The question is, how far do you want to go, and at what point is it not better to write a small .py file which your makefile executes instead?


回答 3


-为了使该答案也适用于Python 3.xprint被称为一个函数:在3.x中, print('foo')适用,而2.x也接受print 'foo'
-有关包括Windows的跨平台观点,请参阅kxr的有用答案

bashkshzsh

使用ANSI C引号的字符串$'...'),该字符串允许使用\n来表示在将字符串传递给之前扩展为实际换行符的换行符python

python -c $'import sys\nfor r in range(10): print("rob")'

注意和语句\n之间的来实现换行符。importfor

要将shell变量值传递给这样的命令,最安全的方法是使用参数并通过sys.argvPython脚本内部访问它们:

name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"

请参阅以下内容,讨论使用带嵌入式外壳变量引用的(转义序列预处理的)双引号命令字符串的优缺点。

为了安全地使用$'...'字符串:

  • \您的原始源代码中的实例。
    • \<char>序列-例如\n在此情况下,也是通常的嫌疑人如\t\r\b-通过膨胀$'...'(参见man printf用于所支持逃逸)
  • '实例转义为\'

如果您必须保持POSIX兼容

使用printf带有命令替换

python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"

为了安全地使用这种类型的字符串:

  • \您的原始源代码中的实例。
    • \<char>序列-例如\n在此情况下,也是通常的嫌疑人如\t\r\b-通过扩展printf(见man printf所支持的转义序列)。
  • 单引号字符串传递给(sic)printf %b转义嵌入的单引号 '\''

    • 使用单引号可以防止shell解释字符串的内容。

      • 也就是说,对于简短的 Python脚本(如本例所示),您可以使用双引号引起来的字符串将shell变量值合并到脚本中-只要您知道相关的陷阱(请参阅下一点);例如,shell扩展$HOME到当前用户的主目录。在以下命令中:

        • python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")"
      • 但是,通常首选的方法是通过参数从shell传递值,并sys.argv在Python中通过访问它们。以上命令的等效项是:

        • python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"
    • 使用双引号的字符串更方便 -它使您可以使用未转义的嵌入式单引号和嵌入式双引号\"–它还使字符串受外壳程序解释,这可能是或不是意图;$`在源代码字符不是用于外壳可能会导致语法错误或意外改变的字符串。

      • 另外,shell自己\在双引号字符串中的处理可能会妨碍您执行;例如,要使Python产生文字输出ro\b,必须将ro\\b其传递给它;用'...'shell字符串和一倍 \的情况下,我们得到:
        python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs'
        相比之下,这的确不是按预期有一张"..."shell字符串:
        python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs'
        Shell解释 "\b""\\b"为文字\b,需要额外的令人眼花缭乱的数字\实例来达到预期的效果:
        python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"

通过传递代码stdin,而不是-c

注意:我在这里专注于单线解决方案。xorho的答案显示了如何使用多行here-document-但是请务必引用定界符;例如,,<<'EOF'除非您明确希望外壳程序将字符串扩展到前面(上述注意事项附带)。


bashkshzsh

结合使用ANSI C引号的字符串$'...')和here字符串<<<...):

python - <<<$'import sys\nfor r in range(10): print("rob")'

-讲述python明确从标准输入读取(其中它在默认情况下)。 -在这种情况下是可选的,但是如果您还想将参数传递给脚本,则需要使用它来消除脚本文件名中的参数歧义:

python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'

如果您必须保持POSIX兼容

printf如上使用,但使用管道以便通过stdin传递其输出:

printf %b 'import sys\nfor r in range(10): print("rob")' | python

带有一个参数:

printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'


– To make this answer work with Python 3.x as well, print is called as a function: in 3.x, only print('foo') works, whereas 2.x also accepts print 'foo'.
– For a cross-platform perspective that includes Windows, see kxr’s helpful answer.

In bash, ksh, or zsh:

Use an ANSI C-quoted string ($'...'), which allows using \n to represent newlines that are expanded to actual newlines before the string is passed to python:

python -c $'import sys\nfor r in range(10): print("rob")'

Note the \n between the import and for statements to effect a line break.

To pass shell-variable values to such a command, it is safest to use arguments and access them via sys.argv inside the Python script:

name='rob' # value to pass to the Python script
python -c $'import sys\nfor r in range(10): print(sys.argv[1])' "$name"

See below for a discussion of the pros and cons of using an (escape sequence-preprocessed) double-quoted command string with embedded shell-variable references.

To work safely with $'...' strings:

  • Double \ instances in your original source code.
    • \<char> sequences – such as \n in this case, but also the usual suspects such as \t, \r, \b – are expanded by $'...' (see man printf for the supported escapes)
  • Escape ' instances as \'.

If you must remain POSIX-compliant:

Use printf with a command substitution:

python -c "$(printf %b 'import sys\nfor r in range(10): print("rob")')"

To work safely with this type of string:

  • Double \ instances in your original source code.
    • \<char> sequences – such as \n in this case, but also the usual suspects such as \t, \r, \b – are expanded by printf (see man printf for the supported escape sequences).
  • Pass a single-quoted string to printf %b and escape embedded single quotes as '\'' (sic).

    • Using single quotes protects the string’s contents from interpretation by the shell.

      • That said, for short Python scripts (as in this case) you can use a double-quoted string to incorporate shell variable values into your scripts – as long as you’re aware of the associated pitfalls (see next point); e.g., the shell expands $HOME to the current user’s home dir. in the following command:

        • python -c "$(printf %b "import sys\nfor r in range(10): print('rob is $HOME')")"
      • However, the generally preferred approach is to pass values from the shell via arguments, and access them via sys.argv in Python; the equivalent of the above command is:

        • python -c "$(printf %b 'import sys\nfor r in range(10): print("rob is " + sys.argv[1])')" "$HOME"
    • While using a double-quoted string is more convenient – it allows you to use embedded single quotes unescaped and embedded double quotes as \" – it also makes the string subject to interpretation by the shell, which may or may not be the intent; $ and ` characters in your source code that are not meant for the shell may cause a syntax error or alter the string unexpectedly.

      • Additionally, the shell’s own \ processing in double-quoted strings can get in the way; for instance, to get Python to produce literal output ro\b, you must pass ro\\b to it; with a '...' shell string and doubled \ instances, we get:
        python -c "$(printf %b 'import sys\nprint("ro\\\\bs")')" # ok: 'ro\bs'
        By contrast, this does not work as intended with a "..." shell string:
        python -c "$(printf %b "import sys\nprint('ro\\\\bs')")" # !! INCORRECT: 'rs'
        The shell interprets both "\b" and "\\b" as literal \b, requiring a dizzying number of additional \ instances to achieve the desired effect:
        python -c "$(printf %b "import sys\nprint('ro\\\\\\\\bs')")"

To pass the code via stdin rather than -c:

Note: I’m focusing on single-line solutions here; xorho’s answer shows how to use a multi-line here-document – be sure to quote the delimiter, however; e.g., <<'EOF', unless you explicitly want the shell to expand the string up front (which comes with the caveats noted above).


In bash, ksh, or zsh:

Combine an ANSI C-quoted string ($'...') with a here-string (<<<...):

python - <<<$'import sys\nfor r in range(10): print("rob")'

- tells python explicitly to read from stdin (which it does by default). - is optional in this case, but if you also want to pass arguments to the scripts, you do need it to disambiguate the argument from a script filename:

python - 'rob' <<<$'import sys\nfor r in range(10): print(sys.argv[1])'

If you must remain POSIX-compliant:

Use printf as above, but with a pipeline so as to pass its output via stdin:

printf %b 'import sys\nfor r in range(10): print("rob")' | python

With an argument:

printf %b 'import sys\nfor r in range(10): print(sys.argv[1])' | python - 'rob'

回答 4

任何想法如何解决?

您的问题是由以下事实引起的:用分隔的Python语句;仅允许为“小语句”,它们都是一线的。从Python文档中的语法文件中:

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | nonlocal_stmt | assert_stmt)

不能通过分号将复合语句与其他语句包含在同一行中,因此使用-c标志执行此操作非常不便。

在bash shell环境中演示Python时,我发现包含复合语句非常有用。可靠地做到这一点的唯一简单方法是使用heredocs(posix shell东西)。

Heredocs

使用定界符(与创建<<)和Python的命令行界面选项-

$ python - <<-"EOF"
        import sys                    # 1 tab indent
        for r in range(10):           # 1 tab indent
            print('rob')              # 1 tab indent and 4 spaces
EOF

添加-after <<<<-)允许您使用制表符缩进(Stackoverflow将制表符转换为空格,因此我缩进了8个空格以强调这一点)。前导标签将被剥离。

您只需使用以下选项卡就可以做到<<

$ python - << "EOF"
import sys
for r in range(10):
    print('rob')
EOF

用引号引起来EOF可防止参数算术扩展。这使heredoc更加健壮。

重击多行字符串

如果使用双引号,则会得到shell扩展:

$ python -c "
> import sys
> for p in '$PATH'.split(':'):
>     print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...

为了避免shell扩展,请使用单引号:

$ python -c '
> import sys
> for p in "$PATH".split(":"):
>     print(p)
> '
$PATH

请注意,我们需要在Python中的文字上交换引号字符-我们基本上不能使用BASH解释的引号字符。虽然我们可以像在Python中那样来替换它们-但这已经看起来很混乱,这就是为什么我不建议这样做的原因:

$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
    print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...

批评接受的答案(和其他)

这不是很可读:

echo -e "import sys\nfor r in range(10): print 'rob'" | python

可读性很差,并且在发生错误时也很难调试:

python -c "exec(\"import sys\\nfor r in range(10): print 'rob'\")"

也许更具可读性,但仍然很丑陋:

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

如果您"的python中有,那么您将度过一段糟糕的时光:

$ python -c "import sys
> for r in range(10): print 'rob'"

不要滥用map或列出理解以获得循环:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

这些都是悲伤和坏的。不要做

Any idea how this can be fixed?

Your problem is created by the fact that Python statements, separated by ;, are only allowed to be “small statements”, which are all one-liners. From the grammar file in the Python docs:

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | nonlocal_stmt | assert_stmt)

Compound statements can’t be included on the same line with other statements via semicolons – so doing this with the -c flag becomes very inconvenient.

When demonstrating Python while in a bash shell environment, I find it very useful to include compound statements. The only simple way of doing this reliably is with heredocs (a posix shell thing).

Heredocs

Use a heredoc (created with <<) and Python’s command line interface option, -:

$ python - <<-"EOF"
        import sys                    # 1 tab indent
        for r in range(10):           # 1 tab indent
            print('rob')              # 1 tab indent and 4 spaces
EOF

Adding the - after << (the <<-) allows you to use tabs to indent (Stackoverflow converts tabs to spaces, so I’ve indented 8 spaces to emphasize this). The leading tabs will be stripped.

You can do it without the tabs with just <<:

$ python - << "EOF"
import sys
for r in range(10):
    print('rob')
EOF

Putting quotes around EOF prevents parameter and arithmetic expansion. This makes the heredoc more robust.

Bash multiline strings

If you use double-quotes, you’ll get shell-expansion:

$ python -c "
> import sys
> for p in '$PATH'.split(':'):
>     print(p)
> "
/usr/sbin
/usr/bin
/sbin
/bin
...

To avoid shell expansion use single-quotes:

$ python -c '
> import sys
> for p in "$PATH".split(":"):
>     print(p)
> '
$PATH

Note that we need to swap the quote characters on the literals in Python – we basically can’t use quote character being interpreted by BASH. We can alternate them though, like we can in Python – but this already looks quite confusing, which is why I don’t recommend this:

$ python -c '
import sys
for p in "'"$PATH"'".split(":"):
    print(p)
'
/usr/sbin
/usr/bin
/sbin
/bin
...

Critique of the accepted answer (and others)

This is not very readable:

echo -e "import sys\nfor r in range(10): print 'rob'" | python

Not very readable, and additionally difficult to debug in the case of an error:

python -c "exec(\"import sys\\nfor r in range(10): print 'rob'\")"

Perhaps a bit more readable, but still quite ugly:

(echo "import sys" ; echo "for r in range(10): print 'rob'") | python

You’ll have a bad time if you have "‘s in your python:

$ python -c "import sys
> for r in range(10): print 'rob'"

Don’t abuse map or list comprehensions to get for-loops:

python -c "import sys; map(lambda x: sys.stdout.write('rob%d\n' % x), range(10))"

These are all sad and bad. Don’t do them.


回答 5

只需使用return并在下一行输入它:

user@host:~$ python -c "import sys
> for r in range(10): print 'rob'"
rob
rob
...

just use return and type it on the next line:

user@host:~$ python -c "import sys
> for r in range(10): print 'rob'"
rob
rob
...

回答 6

$ python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

工作良好。使用“ []”内联for循环。

$ python2.6 -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

Works fine. Use “[ ]” to inline your for loop.


回答 7

问题不在于import语句。问题在于控制流语句无法在python命令中内联。用import其他任何语句替换该语句,您将看到相同的问题。

想想看:python不可能内联所有内容。它使用缩进对控制流进行分组。

The problem is not with the import statement. The problem is that the control flow statements don’t work inlined in a python command. Replace that import statement with any other statement and you’ll see the same problem.

Think about it: python can’t possibly inline everything. It uses indentation to group control-flow.


回答 8

如果您的系统符合Posix.2,则应提供printf实用程序:

$ printf "print 'zap'\nfor r in range(3): print 'rob'" | python
zap
rob
rob
rob

If your system is Posix.2 compliant it should supply the printf utility:

$ printf "print 'zap'\nfor r in range(3): print 'rob'" | python
zap
rob
rob
rob

回答 9

single/double quotesbackslash无处不在:

$ python -c 'exec("import sys\nfor i in range(10): print \"bob\"")'

好多了:

$ python -c '
> import sys
> for i in range(10):
>   print "bob"
> '

single/double quotes and backslash everywhere:

$ python -c 'exec("import sys\nfor i in range(10): print \"bob\"")'

Much better:

$ python -c '
> import sys
> for i in range(10):
>   print "bob"
> '

回答 10

(在10年11月23日,19:48回答) 我并不是一个真正的Pythoner,但是我一次发现了这种语法,却忘记了它的来源,所以我想记录一下它:

如果您使用sys.stdout.write而不是print区别在于,sys.stdout.write将参数作为函数,请放在括号中-而print不是),则对于单行代码,您可以避免颠倒命令的顺序,然后for删除分号,并将命令括在方括号中,即:

python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

不知道如何在Python中调用此语法:)

希望这可以帮助,

干杯!


(2013年4月9日星期二20:57:30 EDIT)好吧,我想我终于找到了这些单线括起来的方括号。它们是“列表理解”(显然);首先请注意Python 2.7:

$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>

因此,圆括号/括号中的命令被视为“生成器对象”;如果我们通过调用“迭代”它next()-括号内的命令将被执行(注意输出中的“ abc”):

$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>

如果我们现在使用方括号-请注意,无需调用next()即可执行命令,它会在分配后立即执行;但是,以后的检查发现aNone

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]

对于方括号,这没有太多信息可寻-但是我偶然发现了该页面,我认为这解释了:

Python技巧和窍门–第一版-Python教程| Dream.In.Code

回想一下,单行生成器的标准格式是括号内的一种“ for”循环。这将产生一个“一次性”可迭代对象,该对象只能在一个方向上迭代,到达终点后就不能重复使用。

“列表理解”看起来与常规单行生成器几乎相同,除了常规方括号-()被方括号-[]代替。列表理解的主要优点是产生了一个“列表”,而不是一个“一次性”的可迭代对象,因此您可以在它之间来回移动,添加元素,排序等。

实际上,它是一个列表-它只是它的第一个元素在执行后立即变为空:

$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None

列表推导5中有其他说明。数据结构:5.1.4。列表推导— Python v2.7.4文档为“列表推导提供了一种创建列表的简洁方法”;大概就是列表的有限“可执行性”发挥作用的地方。

好吧,希望我在这里不会太过分……

EDIT2:这是一个带有两个非嵌套的for循环的单行命令行;都包含在“列表理解”方括号内:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]

注意,第二个“列表” b现在有两个元素,因为它的for循环显式运行了两次;但是,这sys.stdout.write()两种情况的结果都是(显然)None

(answered Nov 23 ’10 at 19:48) I’m not really a big Pythoner – but I found this syntax once, forgot where from, so I thought I’d document it:

if you use sys.stdout.write instead of print (the difference being, sys.stdout.write takes arguments as a function, in parenthesis – whereas print doesn’t), then for a one-liner, you can get away with inverting the order of the command and the for, removing the semicolon, and enclosing the command in square brackets, i.e.:

python -c "import sys; [sys.stdout.write('rob\n') for r in range(10)]"

Have no idea how this syntax would be called in Python :)

Hope this helps,

Cheers!


(EDIT Tue Apr 9 20:57:30 2013) Well, I think I finally found what these square brackets in one-liners are about; they are “list comprehensions” (apparently); first note this in Python 2.7:

$ STR=abc
$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); print a"
<generator object <genexpr> at 0xb771461c>

So the command in round brackets/parenthesis is seen as a “generator object”; if we “iterate” through it by calling next() – then the command inside the parenthesis will be executed (note the “abc” in the output):

$ echo $STR | python -c "import sys,re; a=(sys.stdout.write(line) for line in sys.stdin); a.next() ; print a"
abc
<generator object <genexpr> at 0xb777b734>

If we now use square brackets – note that we don’t need to call next() to have the command execute, it executes immediately upon assignment; however, later inspection reveals that a is None:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; print a"
abc
[None]

This doesn’t leave much info to look for, for the square brackets case – but I stumbled upon this page which I think explains:

Python Tips And Tricks – First Edition – Python Tutorials | Dream.In.Code:

If you recall, the standard format of a single line generator is a kind of one line ‘for’ loop inside brackets. This will produce a ‘one-shot’ iterable object which is an object you can iterate over in only one direction and which you can’t re-use once you reach the end.

A ‘list comprehension’ looks almost the same as a regular one-line generator, except that the regular brackets – ( ) – are replaced by square brackets – [ ]. The major advanatge of alist comprehension is that produces a ‘list’, rather than a ‘one-shot’ iterable object, so that you can go back and forth through it, add elements, sort, etc.

And indeed it is a list – it’s just its first element becomes none as soon as it is executed:

$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin].__class__"
abc
<type 'list'>
$ echo $STR | python -c "import sys,re; print [sys.stdout.write(line) for line in sys.stdin][0]"
abc
None

List comprehensions are otherwise documented in 5. Data Structures: 5.1.4. List Comprehensions — Python v2.7.4 documentation as “List comprehensions provide a concise way to create lists”; presumably, that’s where the limited “executability” of lists comes into play in one-liners.

Well, hope I’m not terribly too off the mark here …

EDIT2: and here is a one-liner command line with two non-nested for-loops; both enclosed within “list comprehension” square brackets:

$ echo $STR | python -c "import sys,re; a=[sys.stdout.write(line) for line in sys.stdin]; b=[sys.stdout.write(str(x)) for x in range(2)] ; print a ; print b"
abc
01[None]
[None, None]

Notice that the second “list” b now has two elements, since its for loop explicitly ran twice; however, the result of sys.stdout.write() in both cases was (apparently) None.


回答 11

此变体最便于移植,用于在Windows和* nix,py2 / 3(不带管道)的命令行上放置多行脚本:

python -c "exec(\"import sys \nfor r in range(10): print('rob') \")"

(到目前为止,这里没有其他示例可以这样做)

在Windows上,整洁的是:

python -c exec"""import sys \nfor r in range(10): print 'rob' """
python -c exec("""import sys \nfor r in range(10): print('rob') """)

bash / * nix的整洁度是:

python -c $'import sys \nfor r in range(10): print("rob")'

此函数将任何多行脚本转换为可移植的命令一列式:

def py2cmdline(script):
    exs = 'exec(%r)' % re.sub('\r\n|\r', '\n', script.rstrip())
    print('python -c "%s"' % exs.replace('"', r'\"'))

用法:

>>> py2cmdline(getcliptext())
python -c "exec('print \'AA\tA\'\ntry:\n for i in 1, 2, 3:\n  print i / 0\nexcept:\n print \"\"\"longer\nmessage\"\"\"')"

输入为:

print 'AA   A'
try:
 for i in 1, 2, 3:
  print i / 0
except:
 print """longer
message"""

This variant is most portable for putting multi-line scripts on command-line on Windows and *nix, py2/3, without pipes:

python -c "exec(\"import sys \nfor r in range(10): print('rob') \")"

(None of the other examples seen here so far did so)

Neat on Windows is:

python -c exec"""import sys \nfor r in range(10): print 'rob' """
python -c exec("""import sys \nfor r in range(10): print('rob') """)

Neat on bash/*nix is:

python -c $'import sys \nfor r in range(10): print("rob")'

This function turns any multiline-script into a portable command-one-liner:

def py2cmdline(script):
    exs = 'exec(%r)' % re.sub('\r\n|\r', '\n', script.rstrip())
    print('python -c "%s"' % exs.replace('"', r'\"'))

Usage:

>>> py2cmdline(getcliptext())
python -c "exec('print \'AA\tA\'\ntry:\n for i in 1, 2, 3:\n  print i / 0\nexcept:\n print \"\"\"longer\nmessage\"\"\"')"

Input was:

print 'AA   A'
try:
 for i in 1, 2, 3:
  print i / 0
except:
 print """longer
message"""

回答 12

该脚本提供了类似Perl的命令行界面:

Pyliner-在命令行上运行任意Python代码的脚本(Python配方)


回答 13

当我需要这样做时,我使用

python -c "$(echo -e "import sys\nsys.stdout.write('Hello World!\\\n')")"

注意sys.stdout.write语句中换行符的三倍反斜杠。

When I needed to do this, I use

python -c "$(echo -e "import sys\nsys.stdout.write('Hello World!\\\n')")"

Note the triple backslash for the newline in the sys.stdout.write statement.


回答 14

我想要一个具有以下属性的解决方案:

  1. 可读的
  2. 阅读stdin来处理其他工具的输出

其他答案中未同时提供这两个要求,因此,这是在命令行上执行所有操作时如何读取stdin的方法:

grep special_string -r | sort | python3 <(cat <<EOF
import sys
for line in sys.stdin:
    tokens = line.split()
    if len(tokens) == 4:
        print("%-45s %7.3f    %s    %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
EOF
)

I wanted a solution with the following properties:

  1. Readable
  2. Read stdin for processing output of other tools

Both requirements were not provided in the other answers, so here’s how to read stdin while doing everything on the command line:

grep special_string -r | sort | python3 <(cat <<EOF
import sys
for line in sys.stdin:
    tokens = line.split()
    if len(tokens) == 4:
        print("%-45s %7.3f    %s    %s" % (tokens[0], float(tokens[1]), tokens[2], tokens[3]))
EOF
)

回答 15

还有一个选项,sys.stdout.write返回None,使列表为空

cat somefile.log | python -c“ import sys; [如果sys.stdout.write(line * 2),则为sys.stdin中的行的一行]”

there is one more option, sys.stdout.write returns None, which keep the list empty

cat somefile.log|python -c "import sys;[line for line in sys.stdin if sys.stdout.write(line*2)]"

回答 16

如果您不想触摸stdin并像传递“ python cmdfile.py”一样进行模拟,则可以从bash shell执行以下操作:

$ python  <(printf "word=raw_input('Enter word: ')\nimport sys\nfor i in range(5):\n    print(word)")

如您所见,它允许您使用stdin读取输入数据。在内部,shell为输入命令内容创建临时文件。

If you don’t want to touch stdin and simulate as if you had passed “python cmdfile.py”, you can do the following from a bash shell:

$ python  <(printf "word=raw_input('Enter word: ')\nimport sys\nfor i in range(5):\n    print(word)")

As you can see, it allows you to use stdin for reading input data. Internally the shell creates the temporary file for the input command contents.


Hug 使API开发尽可能简单


Hug的目标是使开发Python驱动的API尽可能简单,但并不简单。因此,它极大地简化了Python API开发

Hug的设计目标:

  • 使开发Python驱动的API与书面定义一样简洁
  • 框架应该鼓励编写自我文档代码
  • 它应该是快的。出于性能原因,开发人员永远不会觉得有必要寻找其他地方。
  • 为在Hug之上编写的API编写测试应该是简单而直观的
  • 在API框架中只做一次比将问题集推给API框架的用户要好
  • 成为下一代Python API的基础,采用最新技术

作为这些目标的结果,Hug仅支持Python3+,并且是在此基础上构建的Falcon’s高性能HTTP库

支持拥抱发展

Get professionally supported hug with the Tidelift Subscription

拥抱的专业支持是作为Tidelift
Subscription
Tidelift为软件开发团队提供了购买和维护软件的单一来源,并由最了解该技术的专家提供专业级别保证,同时与现有工具无缝集成

安装拥抱

安装Hug非常简单,只需:

pip3 install hug --upgrade

理想情况下,在virtual environment

快速入门

只需几行代码即可使用简单端点构建示例API

# filename: happy_birthday.py
"""A basic (single function) API written using hug"""
import hug


@hug.get('/happy_birthday')
def happy_birthday(name, age:hug.types.number=1):
    """Says happy birthday to a user"""
    return "Happy {age} Birthday {name}!".format(**locals())

要运行,请在命令行中键入:

hug -f happy_birthday.py

您可以在浏览器中访问该示例,网址为:localhost:8000/happy_birthday?name=hug&age=1然后在以下位置查看您的API的文档localhost:8000/documentation

参数也可以在URL中编码(签出happy_birthday.py对于整个示例)

@hug.get('/greet/{event}')
def greet(event: str):
    """Greets appropriately (from http://blog.ketchum.com/how-to-write-10-common-holiday-greetings/)  """
    greetings = "Happy"
    if event == "Christmas":
        greetings = "Merry"
    if event == "Kwanzaa":
        greetings = "Joyous"
    if event == "wishes":
        greetings = "Warm"

    return "{greetings} {event}!".format(**locals())

一旦您按照上述方式运行服务器,您就可以通过以下方式使用它:

curl http://localhost:8000/greet/wishes
"Warm wishes!"

拥抱着版本化

# filename: versioning_example.py
"""A simple example of a hug API call with versioning"""
import hug

@hug.get('/echo', versions=1)
def echo(text):
    return text


@hug.get('/echo', versions=range(2, 5))
def echo(text):
    return "Echo: {text}".format(**locals())

要运行示例,请执行以下操作:

hug -f versioning_example.py

然后,您可以从以下位置访问该示例localhost:8000/v1/echo?text=Hi/localhost:8000/v2/echo?text=Hi或从以下地址访问您的API的文档localhost:8000

注意:Hug中的版本控制自动支持版本头和直接基于URL的规范

Hug接口测试

拥抱的http方法装饰器不会修改您的原始函数。这使得测试Hug API与测试任何其他Python函数一样简单。此外,这意味着与其他Python代码中的API函数交互与仅调用Python API函数一样简单。Hug使测试API的完整Python堆栈变得容易,方法是使用hug.test模块:

import hug
import happy_birthday

hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25}) # Returns a Response object

你可以用这个Response测试断言的对象(签出test_happy_birthday.py):

def tests_happy_birthday():
    response = hug.test.get(happy_birthday, 'happy_birthday', {'name': 'Timothy', 'age': 25})
    assert response.status == HTTP_200
    assert response.data is not None

与其他基于WSGI的服务器运行Hug

拥抱暴露出一种__hug_wsgi__自动在每个API模块上使用魔法方法。在任何标准的WSGI服务器上运行基于Hug的API都应该很简单,只需将其指向module_name__hug_wsgi__

例如:

uwsgi --http 0.0.0.0:8000 --wsgi-file examples/hello_world.py --callable __hug_wsgi__

要运行hello world hug示例API,请执行以下操作

Hug API的构建块

在使用Hug框架构建API时,您将使用以下概念:

方法装饰器getpostupdate等HTTP方法修饰器,在保持Python方法不变的同时将Python函数公开为API

@hug.get() # <- Is the hug METHOD decorator
def hello_world():
    return "Hello"

Hug使用您修饰的函数结构自动为API用户生成文档。Hug始终将请求、响应和API_VERSION变量传递给函数(如果它们是在函数定义中定义的参数

类型批注可选地附加到方法参数的函数,用于指定如何验证参数并将其转换为Python类型

@hug.get()
def math(number_1:int, number_2:int): #The :int after both arguments is the Type Annotation
    return number_1 + number_2

类型批注还会馈送到hug的自动文档生成,让API用户知道要提供什么数据

指令与请求/响应数据一起执行的函数,这些函数基于在API_Function中作为参数被请求。这些仅作为输入参数应用,当前不能作为输出格式或转换应用

@hug.get()
def test_time(hug_timer):
    return {'time_taken': float(hug_timer)}

指令可以通过带有hug_前缀,或使用Python3类型批注。后者是更现代的方法,建议使用。模块中声明的指令可以通过使用它们的完全限定名作为类型注释来访问(例如:module.directive_name)

除了明显的输入转换用例之外,还可以使用指令将数据输送到API函数中,即使它们没有出现在请求查询字符串、POST正文等中。有关如何以这种方式使用指令的示例,请参阅Examples文件夹中的身份验证示例

添加您自己的指令非常简单:

@hug.directive()
def square(value=1, **kwargs):
    '''Returns passed in parameter multiplied by itself'''
    return value * value

@hug.get()
@hug.local()
def tester(value: square=10):
    return value

tester() == 100

为完整起见,下面是通过魔术名称方法访问指令的示例:

@hug.directive()
def multiply(value=1, **kwargs):
    '''Returns passed in parameter multiplied by itself'''
    return value * value

@hug.get()
@hug.local()
def tester(hug_multiply=10):
    return hug_multiply

tester() == 100

输出表单事项获取API函数的输出并对其进行格式化以便传输给API用户的函数

@hug.default_output_format()
def my_output_formatter(data):
    return "STRING:{0}".format(data)

@hug.get(output=hug.output_format.json)
def hello():
    return {'hello': 'world'}

如图所示,您可以轻松地更改整个API和单个API调用的输出格式

输入表事项一个函数,它从API的用户处获取数据体,并对其进行格式化以进行处理

@hug.default_input_format("application/json")
def my_input_formatter(data):
    return ('Results', hug.input_format.json(data))

输入格式化程序基于content_type请求数据,并且仅执行基本解析。更详细的解析应该由您的api_function

中间件Hug API处理的每个请求都会调用的函数

@hug.request_middleware()
def process_data(request, response):
    request.env['SERVER_NAME'] = 'changed'

@hug.response_middleware()
def process_data(request, response, resource):
    response.set_header('MyHeader', 'Value')

您还可以使用以下工具轻松添加任何Falcon样式的中间件:

__hug__.http.add_middleware(MiddlewareObject())

参数映射可用于覆盖推断的参数名称,例如。对于保留关键字:

import marshmallow.fields as fields
...

@hug.get('/foo', map_params={'from': 'from_date'})  # API call uses 'from'
def get_foo_by_date(from_date: fields.DateTime()):
    return find_foo(from_date)

输入格式化程序基于content_type请求数据,并且仅执行基本解析。更详细的解析应该由您的api_function

多文件拆分API

Hug使您能够以任何您认为合适的方式组织大型项目。您可以导入任何包含Hug修饰函数(请求处理、指令、类型处理程序等)的模块,并使用该模块扩展您的基础API

例如:

something.py

import hug

@hug.get('/')
def say_hi():
    return 'hello from something'

可以导入到主API文件中:

__init__.py

import hug
from . import something

@hug.get('/')
def say_hi():
    return "Hi from root"

@hug.extend_api('/something')
def something_api():
    return [something]

或者,对于这样的情况,每个URL路由只包含一个模块:

#alternatively
hug.API(__name__).extend(something, '/something')

配置拥抱404

默认情况下,当用户尝试访问未定义的端点时,Hug返回自动生成的API规范。如果您不想退还此规范,可以关闭404文档:

从命令行应用程序执行以下操作:

hug -nd -f {file} #nd flag tells hug not to generate documentation on 404

此外,您还可以轻松创建自定义404处理程序,方法是使用hug.not_found装饰师:

@hug.not_found()
def not_found_handler():
    return "Not Found"

此修饰器的工作方式与Hug HTTP方法修饰器相同,甚至可以识别版本:

@hug.not_found(versions=1)
def not_found_handler():
    return ""

@hug.not_found(versions=2)
def not_found_handler():
    return "Not Found"

Asyncio支持

在使用getcli协程上的方法修饰器,Hug将调度协程的执行

使用异步协同程序装饰器

@hug.get()
@asyncio.coroutine
def hello_world():
    return "Hello"

使用Python 3.5异步关键字

@hug.get()
async def hello_world():
    return "Hello"

注意:Hug在顶部的Falcon上运行,它不是异步服务器。即使使用Asyncio,仍将同步处理请求

使用Docker

如果您希望在Docker中进行开发并保持系统整洁,您可以这样做,但您需要首先安装Docker Compose

一旦你这样做了,你就需要cd进入到docker目录并运行中指定的Web服务器(Gunicorn./docker/gunicorn/Dockerfile之后,您可以在主机上的浏览器中预览API的输出

$ cd ./docker
# This will run Gunicorn on port 8000 of the Docker container.
$ docker-compose up gunicorn

# From the host machine, find your Dockers IP address.
# For Windows & Mac:
$ docker-machine ip default

# For Linux:
$ ifconfig docker0 | grep 'inet' | cut -d: -f2 | awk '{ print $1}' | head -n1

默认情况下,IP为172.17.0.1。假设这也是您看到的IP,那么您将转到http://172.17.0.1:8000/在您的浏览器中查看您的API

您还可以登录到可以考虑您的工作空间的Docker容器。此工作区安装了Python和Pip,因此您可以在Docker中使用这些工具。例如,如果您需要测试CLI接口,您可以使用以下代码

$ docker-compose run workspace bash

在你的码头上workspace容器中的./docker/templates主计算机上的目录挂载到/src在码头集装箱里。这是在下指定的services>app./docker/docker-compose.yml

bash-4.3# cd /src
bash-4.3# tree
.
├── __init__.py
└── handlers
    ├── birthday.py
    └── hello.py

1 directory, 3 files

安全联系信息

Hug认真对待安全和质量。这就是为什么我们只依赖经过彻底测试的组件并利用静电分析工具(如Banddit和SAFE)来验证我们代码库的安全性的原因。如果您发现或遇到任何潜在的安全问题,请立即通知我们,以便我们解决

若要报告安全漏洞,请使用Tidelift security contactTidelift将协调修复和披露

为什么要拥抱?

拥抱只是希望有用的向导的意思。这代表了该项目的目标,即帮助指导开发人员创建编写良好且直观的API


谢谢,我希望你能找到拥抱对您开发下一个Python API很有帮助!

~蒂莫西·克罗斯利

解析命令行参数的最佳方法是什么?[关闭]

问题:解析命令行参数的最佳方法是什么?[关闭]

什么是最简单的tersest,最灵活的方法或库解析Python的命令行参数?

What’s the easiest, tersest, and most flexible method or library for parsing Python command line arguments?


回答 0

该答案表明optparse哪种方法适用于较旧的Python版本。对于Python 2.7及更高版本,请argparse替换optparse。有关更多信息,请参见此答案

正如其他人指出的那样,您最好使用optparse而不是getopt。getopt几乎是标准getopt(3)C库函数的一对一映射,并且使用起来不是很容易。

optparse较为冗长,但结构更好,以后也更易于扩展。

这是向解析器添加选项的典型行:

parser.add_option('-q', '--query',
            action="store", dest="query",
            help="query string", default="spam")

这几乎可以说明一切。在处理时,它将接受-q或–query作为选项,将参数存储在名为query的属性中,如果未指定,则具有默认值。它也是自记录的,您可以在该选项的附近声明help参数(与-h /-help一起使用时将使用该参数)。

通常,您使用以下方法解析参数:

options, args = parser.parse_args()

默认情况下,这将解析传递给脚本的标准参数(sys.argv [1:])

然后,将options.query设置为您传递给脚本的值。

您只需执行以下操作即可创建解析器

parser = optparse.OptionParser()

这些都是您需要的所有基本知识。这是显示此内容的完整Python脚本:

import optparse

parser = optparse.OptionParser()

parser.add_option('-q', '--query',
    action="store", dest="query",
    help="query string", default="spam")

options, args = parser.parse_args()

print 'Query string:', options.query

5行Python,向您展示基础知识。

将其保存在sample.py中,然后运行一次

python sample.py

然后一次

python sample.py --query myquery

除此之外,您还会发现optparse非常容易扩展。在我的一个项目中,我创建了一个Command类,该类使您可以轻松地将子命令嵌套在命令树中。它大量使用optparse将命令链接在一起。这不是我可以轻松地解释的内容,但是可以在我的存储库中随意浏览主类以及使用它的类和选项解析器

This answer suggests optparse which is appropriate for older Python versions. For Python 2.7 and above, argparse replaces optparse. See this answer for more information.

As other people pointed out, you are better off going with optparse over getopt. getopt is pretty much a one-to-one mapping of the standard getopt(3) C library functions, and not very easy to use.

optparse, while being a bit more verbose, is much better structured and simpler to extend later on.

Here’s a typical line to add an option to your parser:

parser.add_option('-q', '--query',
            action="store", dest="query",
            help="query string", default="spam")

It pretty much speaks for itself; at processing time, it will accept -q or –query as options, store the argument in an attribute called query and has a default value if you don’t specify it. It is also self-documenting in that you declare the help argument (which will be used when run with -h/–help) right there with the option.

Usually you parse your arguments with:

options, args = parser.parse_args()

This will, by default, parse the standard arguments passed to the script (sys.argv[1:])

options.query will then be set to the value you passed to the script.

You create a parser simply by doing

parser = optparse.OptionParser()

These are all the basics you need. Here’s a complete Python script that shows this:

import optparse

parser = optparse.OptionParser()

parser.add_option('-q', '--query',
    action="store", dest="query",
    help="query string", default="spam")

options, args = parser.parse_args()

print 'Query string:', options.query

5 lines of python that show you the basics.

Save it in sample.py, and run it once with

python sample.py

and once with

python sample.py --query myquery

Beyond that, you will find that optparse is very easy to extend. In one of my projects, I created a Command class which allows you to nest subcommands in a command tree easily. It uses optparse heavily to chain commands together. It’s not something I can easily explain in a few lines, but feel free to browse around in my repository for the main class, as well as a class that uses it and the option parser


回答 1

argparse是要走的路。以下是使用方法的简短摘要:

1)初始化

import argparse

# Instantiate the parser
parser = argparse.ArgumentParser(description='Optional app description')

2)添加参数

# Required positional argument
parser.add_argument('pos_arg', type=int,
                    help='A required integer positional argument')

# Optional positional argument
parser.add_argument('opt_pos_arg', type=int, nargs='?',
                    help='An optional integer positional argument')

# Optional argument
parser.add_argument('--opt_arg', type=int,
                    help='An optional integer argument')

# Switch
parser.add_argument('--switch', action='store_true',
                    help='A boolean switch')

3)解析

args = parser.parse_args()

4)访问

print("Argument values:")
print(args.pos_arg)
print(args.opt_pos_arg)
print(args.opt_arg)
print(args.switch)

5)检查值

if args.pos_arg > 10:
    parser.error("pos_arg cannot be larger than 10")

用法

正确使用:

$ ./app 1 2 --opt_arg 3 --switch

Argument values:
1
2
3
True

不正确的参数:

$ ./app foo 2 --opt_arg 3 --switch
usage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
app: error: argument pos_arg: invalid int value: 'foo'

$ ./app 11 2 --opt_arg 3
Argument values:
11
2
3
False
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
convert: error: pos_arg cannot be larger than 10

全面帮助:

$ ./app -h

usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]

Optional app description

positional arguments:
  pos_arg            A required integer positional argument
  opt_pos_arg        An optional integer positional argument

optional arguments:
  -h, --help         show this help message and exit
  --opt_arg OPT_ARG  An optional integer argument
  --switch           A boolean switch

argparse is the way to go. Here is a short summary of how to use it:

1) Initialize

import argparse

# Instantiate the parser
parser = argparse.ArgumentParser(description='Optional app description')

2) Add Arguments

# Required positional argument
parser.add_argument('pos_arg', type=int,
                    help='A required integer positional argument')

# Optional positional argument
parser.add_argument('opt_pos_arg', type=int, nargs='?',
                    help='An optional integer positional argument')

# Optional argument
parser.add_argument('--opt_arg', type=int,
                    help='An optional integer argument')

# Switch
parser.add_argument('--switch', action='store_true',
                    help='A boolean switch')

3) Parse

args = parser.parse_args()

4) Access

print("Argument values:")
print(args.pos_arg)
print(args.opt_pos_arg)
print(args.opt_arg)
print(args.switch)

5) Check Values

if args.pos_arg > 10:
    parser.error("pos_arg cannot be larger than 10")

Usage

Correct use:

$ ./app 1 2 --opt_arg 3 --switch

Argument values:
1
2
3
True

Incorrect arguments:

$ ./app foo 2 --opt_arg 3 --switch
usage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
app: error: argument pos_arg: invalid int value: 'foo'

$ ./app 11 2 --opt_arg 3
Argument values:
11
2
3
False
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
convert: error: pos_arg cannot be larger than 10

Full help:

$ ./app -h

usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]

Optional app description

positional arguments:
  pos_arg            A required integer positional argument
  opt_pos_arg        An optional integer positional argument

optional arguments:
  -h, --help         show this help message and exit
  --opt_arg OPT_ARG  An optional integer argument
  --switch           A boolean switch

回答 2

使用docopt

自2012年以来,有一个非常简单,功能强大且非常的参数解析模块docopt。这是取自其文档的示例:

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

因此,这是它:两行代码加上您的文档字符串,它必不可少的,你会得到你的参数解析,并在你的论点对象可用。

使用python-fire

自2017年以来,还有一个很酷的模块称为python-fire。通过执行参数解析,它可以为您的代码生成CLI接口。这是文档中的一个简单示例(这个小程序将功能公开double给命令行):

import fire

class Calculator(object):

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)

在命令行中,您可以运行:

> calculator.py double 10
20
> calculator.py double --number=15
30

Using docopt

Since 2012 there is a very easy, powerful and really cool module for argument parsing called docopt. Here is an example taken from its documentation:

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

So this is it: 2 lines of code plus your doc string which is essential and you get your arguments parsed and available in your arguments object.

Using python-fire

Since 2017 there’s another cool module called python-fire. It can generate a CLI interface for your code with you doing zero argument parsing. Here’s a simple example from the documentation (this small program exposes the function double to the command line):

import fire

class Calculator(object):

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)

From the command line, you can run:

> calculator.py double 10
20
> calculator.py double --number=15
30

回答 3

新的髋关节的方法是argparse这些原因。argparse> optparse> getopt

更新:自py2.7起,argparse已成为标准库的一部分,而optparse已弃用。

The new hip way is argparse for these reasons. argparse > optparse > getopt

update: As of py2.7 argparse is part of the standard library and optparse is deprecated.


回答 4

我更喜欢点击。它抽象化了管理选项,并允许“(…)以可组合的方式用所需的最少代码创建漂亮的命令行界面”。

这是示例用法:

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

它还会自动生成格式正确的帮助页面:

$ python hello.py --help
Usage: hello.py [OPTIONS]

  Simple program that greets NAME for a total of COUNT times.

Options:
  --count INTEGER  Number of greetings.
  --name TEXT      The person to greet.
  --help           Show this message and exit.

I prefer Click. It abstracts managing options and allows “(…) creating beautiful command line interfaces in a composable way with as little code as necessary”.

Here’s example usage:

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

It also automatically generates nicely formatted help pages:

$ python hello.py --help
Usage: hello.py [OPTIONS]

  Simple program that greets NAME for a total of COUNT times.

Options:
  --count INTEGER  Number of greetings.
  --name TEXT      The person to greet.
  --help           Show this message and exit.

回答 5

几乎每个人都在使用getopt

这是doc的示例代码:

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

简而言之,这就是它的工作原理。

您有两种选择。那些接受论证的人,以及那些像开关的人。

sys.argvchar** argv在C中几乎就是您。与C中一样,您跳过第一个元素(它是程序的名称),并且仅解析参数:sys.argv[1:]

Getopt.getopt 将根据您在参数中给出的规则对其进行解析。

"ho:v"这里描述简短的论点:-ONELETTER。接受一个论点的:手段-o

最后["help", "output="]介绍长参数(--MORETHANONELETTER)。在=后输出再次意味着输出接受一个参数。

结果是一对夫妇(选项,参数)的列表

如果选项不接受任何参数(例如--help此处),则该arg部分为空字符串。然后,您通常希望在此列表上循环并测试示例中的选项名称。

希望对您有所帮助。

Pretty much everybody is using getopt

Here is the example code for the doc :

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

So in a word, here is how it works.

You’ve got two types of options. Those who are receiving arguments, and those who are just like switches.

sys.argv is pretty much your char** argv in C. Like in C you skip the first element which is the name of your program and parse only the arguments : sys.argv[1:]

Getopt.getopt will parse it according to the rule you give in argument.

"ho:v" here describes the short arguments : -ONELETTER. The : means that -o accepts one argument.

Finally ["help", "output="] describes long arguments ( --MORETHANONELETTER ). The = after output once again means that output accepts one arguments.

The result is a list of couple (option,argument)

If an option doesn’t accept any argument (like --help here) the arg part is an empty string. You then usually want to loop on this list and test the option name as in the example.

I hope this helped you.


回答 6

使用optparse标准库随附的。例如:

#!/usr/bin/env python
import optparse

def main():
  p = optparse.OptionParser()
  p.add_option('--person', '-p', default="world")
  options, arguments = p.parse_args()
  print 'Hello %s' % options.person

if __name__ == '__main__':
  main()

来源:使用Python创建UNIX命令行工具

但是,自python 2.7起,不建议使用optparse,请参阅:为什么使用argparse而不是optparse?

Use optparse which comes with the standard library. For example:

#!/usr/bin/env python
import optparse

def main():
  p = optparse.OptionParser()
  p.add_option('--person', '-p', default="world")
  options, arguments = p.parse_args()
  print 'Hello %s' % options.person

if __name__ == '__main__':
  main()

Source: Using Python to create UNIX command line tools

However as of Python 2.7 optparse is deprecated, see: Why use argparse rather than optparse?


回答 7

万一您可能需要,如果您需要在Win32(2K,XP等)上获取 unicode参数,这可能会有所帮助:


from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()

Just in case you might need to, this may help if you need to grab unicode arguments on Win32 (2K, XP etc):


from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()

回答 8

轻量级命令行参数默认值

尽管argparse这很好,并且是完全记录的命令行开关和高级功能的正确答案,但是您可以使用函数参数默认值来非常简单地处理简单的位置参数。

import sys

def get_args(name='default', first='a', second=2):
    return first, int(second)

first, second = get_args(*sys.argv)
print first, second

‘name’参数捕获脚本名称,并且不使用。测试输出如下所示:

> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20

对于只需要一些默认值的简单脚本,我发现这已经足够了。您可能还希望在返回值中包含某种类型的强制,否则命令行值将全部为字符串。

Lightweight command line argument defaults

Although argparse is great and is the right answer for fully documented command line switches and advanced features, you can use function argument defaults to handles straightforward positional arguments very simply.

import sys

def get_args(name='default', first='a', second=2):
    return first, int(second)

first, second = get_args(*sys.argv)
print first, second

The ‘name’ argument captures the script name and is not used. Test output looks like this:

> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20

For simple scripts where I just want some default values, I find this quite sufficient. You might also want to include some type coercion in the return values or command line values will all be strings.


回答 9

我更喜欢optparse而不是getopt。这是非常具有说明性的:您告诉它选项的名称以及它们应具有的效果(例如,设置布尔字段),它会根据您的规范将您交给的字典交给您。

http://docs.python.org/lib/module-optparse.html

I prefer optparse to getopt. It’s very declarative: you tell it the names of the options and the effects they should have (e.g., setting a boolean field), and it hands you back a dictionary populated according to your specifications.

http://docs.python.org/lib/module-optparse.html


回答 10

我认为大型项目的最佳方法是optparse,但是如果您正在寻找一种简单的方法,那么http://werkzeug.pocoo.org/documentation/script可能适合您。

from werkzeug import script

# actions go here
def action_foo(name=""):
    """action foo does foo"""
    pass

def action_bar(id=0, title="default title"):
    """action bar does bar"""
    pass

if __name__ == '__main__':
    script.run()

因此,基本上每个函数action_ *都会在命令行中显示,并且会免费生成一个不错的帮助消息。

python foo.py 
usage: foo.py <action> [<options>]
       foo.py --help

actions:
  bar:
    action bar does bar

    --id                          integer   0
    --title                       string    default title

  foo:
    action foo does foo

    --name                        string

I think the best way for larger projects is optparse, but if you are looking for an easy way, maybe http://werkzeug.pocoo.org/documentation/script is something for you.

from werkzeug import script

# actions go here
def action_foo(name=""):
    """action foo does foo"""
    pass

def action_bar(id=0, title="default title"):
    """action bar does bar"""
    pass

if __name__ == '__main__':
    script.run()

So basically every function action_* is exposed to the command line and a nice help message is generated for free.

python foo.py 
usage: foo.py <action> [<options>]
       foo.py --help

actions:
  bar:
    action bar does bar

    --id                          integer   0
    --title                       string    default title

  foo:
    action foo does foo

    --name                        string

回答 11

Argparse代码可以比实际的实现代码更长!

我发现最流行的参数解析选项存在一个问题,就是如果您的参数仅适中,则用于记录它们的代码对于它们提供的好处而言会变得过大。

我认为参数解析场景的一个相对较新的东西是plac

它使用argparse进行了一些公认的折衷,但是使用了内联文档并仅将main()类型函数包装为:

def main(excel_file_path: "Path to input training file.",
     excel_sheet_name:"Name of the excel sheet containing training data including columns 'Label' and 'Description'.",
     existing_model_path: "Path to an existing model to refine."=None,
     batch_size_start: "The smallest size of any minibatch."=10.,
     batch_size_stop:  "The largest size of any minibatch."=250.,
     batch_size_step:  "The step for increase in minibatch size."=1.002,
     batch_test_steps: "Flag.  If True, show minibatch steps."=False):
"Train a Spacy (http://spacy.io/) text classification model with gold document and label data until the model nears convergence (LOSS < 0.5)."

    pass # Implementation code goes here!

if __name__ == '__main__':
    import plac; plac.call(main)

Argparse code can be longer than actual implementation code!

That’s a problem I find with most popular argument parsing options is that if your parameters are only modest, the code to document them becomes disproportionately large to the benefit they provide.

A relative new-comer to the argument parsing scene (I think) is plac.

It makes some acknowledged trade-offs with argparse, but uses inline documentation and wraps simply around main() type function function:

def main(excel_file_path: "Path to input training file.",
     excel_sheet_name:"Name of the excel sheet containing training data including columns 'Label' and 'Description'.",
     existing_model_path: "Path to an existing model to refine."=None,
     batch_size_start: "The smallest size of any minibatch."=10.,
     batch_size_stop:  "The largest size of any minibatch."=250.,
     batch_size_step:  "The step for increase in minibatch size."=1.002,
     batch_test_steps: "Flag.  If True, show minibatch steps."=False):
"Train a Spacy (http://spacy.io/) text classification model with gold document and label data until the model nears convergence (LOSS < 0.5)."

    pass # Implementation code goes here!

if __name__ == '__main__':
    import plac; plac.call(main)

回答 12

consoleargs在这里值得一提。这是非常容易使用。看看这个:

from consoleargs import command

@command
def main(url, name=None):
  """
  :param url: Remote URL 
  :param name: File name
  """
  print """Downloading url '%r' into file '%r'""" % (url, name)

if __name__ == '__main__':
  main()

现在在控制台中:

% python demo.py --help
Usage: demo.py URL [OPTIONS]

URL:    Remote URL 

Options:
    --name -n   File name

% python demo.py http://www.google.com/
Downloading url ''http://www.google.com/'' into file 'None'

% python demo.py http://www.google.com/ --name=index.html
Downloading url ''http://www.google.com/'' into file ''index.html''

consoleargs deserves to be mentioned here. It is very easy to use. Check it out:

from consoleargs import command

@command
def main(url, name=None):
  """
  :param url: Remote URL 
  :param name: File name
  """
  print """Downloading url '%r' into file '%r'""" % (url, name)

if __name__ == '__main__':
  main()

Now in console:

% python demo.py --help
Usage: demo.py URL [OPTIONS]

URL:    Remote URL 

Options:
    --name -n   File name

% python demo.py http://www.google.com/
Downloading url ''http://www.google.com/'' into file 'None'

% python demo.py http://www.google.com/ --name=index.html
Downloading url ''http://www.google.com/'' into file ''index.html''

回答 13

这是一种对我有用的方法,而不是库。

这里的目标是简洁的,每个参数都由一行解析,args排列以提高可读性,代码简单且不依赖任何特殊模块(仅os + sys),优雅地警告缺少或未知的参数,使用简单的for / range()循环,即可在python 2.x和3.x上运行

显示的是两个切换标志(-d,-v)和两个由参数控制的值(-i xxx和-o xxx)。

import os,sys

def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"

    # Parse command line
    skip = 0
    for i in range(1, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("%d,%d,%s,%s" % (debug,verbose,infile,outfile))

NextArg()的目标是在检查缺少的数据时返回下一个参数,并且在使用NextArg()时,“ skip”跳过循环,从而将标志解析到一个衬里。

Here’s a method, not a library, which seems to work for me.

The goals here are to be terse, each argument parsed by a single line, the args line up for readability, the code is simple and doesn’t depend on any special modules (only os + sys), warns about missing or unknown arguments gracefully, use a simple for/range() loop, and works across python 2.x and 3.x

Shown are two toggle flags (-d, -v), and two values controlled by arguments (-i xxx and -o xxx).

import os,sys

def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"

    # Parse command line
    skip = 0
    for i in range(1, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("%d,%d,%s,%s" % (debug,verbose,infile,outfile))

The goal of NextArg() is to return the next argument while checking for missing data, and ‘skip’ skips the loop when NextArg() is used, keeping the flag parsing down to one liners.


回答 14

我扩展了Erco的方法,以允许使用必需的位置参数和可选参数。这些应在-d,-v等参数之前。

位置和可选参数可以分别使用PosArg(i)和OptArg(i,默认值)检索。当找到一个可选参数时,搜索选项的起始位置(例如-i)将向前移动1,以避免造成“意外”的致命事故。

import os,sys


def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

def PosArg(i):
    '''Return positional argument'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return sys.argv[i]

def OptArg(i, default):
    '''Return optional argument (if there is one)'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    if sys.argv[i][:1] != '-':
        return True, sys.argv[i]
    else:
        return False, default


### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"
    options_start = 3

    # --- Parse two positional parameters ---
    n1 = int(PosArg(1))
    n2 = int(PosArg(2))

    # --- Parse an optional parameters ---
    present, a3 = OptArg(3,50)
    n3 = int(a3)
    options_start += int(present)

    # --- Parse rest of command line ---
    skip = 0
    for i in range(options_start, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("Number 1 = %d" % n1)
    print("Number 2 = %d" % n2)
    print("Number 3 = %d" % n3)
    print("Debug    = %d" % debug)
    print("verbose  = %d" % verbose)
    print("infile   = %s" % infile)
    print("outfile  = %s" % outfile) 

I extended Erco’s approach to allow for required positional arguments and for optional arguments. These should precede the -d, -v etc. arguments.

Positional and optional arguments can be retrieved with PosArg(i) and OptArg(i, default) respectively. When an optional argument is found the start position of searching for options (e.g. -i) is moved 1 ahead to avoid causing an ‘unexpected’ fatal.

import os,sys


def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

def PosArg(i):
    '''Return positional argument'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return sys.argv[i]

def OptArg(i, default):
    '''Return optional argument (if there is one)'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    if sys.argv[i][:1] != '-':
        return True, sys.argv[i]
    else:
        return False, default


### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"
    options_start = 3

    # --- Parse two positional parameters ---
    n1 = int(PosArg(1))
    n2 = int(PosArg(2))

    # --- Parse an optional parameters ---
    present, a3 = OptArg(3,50)
    n3 = int(a3)
    options_start += int(present)

    # --- Parse rest of command line ---
    skip = 0
    for i in range(options_start, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("Number 1 = %d" % n1)
    print("Number 2 = %d" % n2)
    print("Number 3 = %d" % n3)
    print("Debug    = %d" % debug)
    print("verbose  = %d" % verbose)
    print("infile   = %s" % infile)
    print("outfile  = %s" % outfile) 

Python在git bash的命令行中不起作用

问题:Python在git bash的命令行中不起作用

Python无法在git bash(Windows)中运行。当我在命令行中键入python时,它带我进入空白行,而无需说它像在Powershell中一样已经输入了python 2.7.10。它不会给我错误消息,但是python不会运行。

我已经确定PATH中的环境变量包括在内c:\python27。我还能检查什么?


发生此问题的会话如下所示:

user@hostname MINGW64 ~
$ type python
python is /c/Python27/python

user@hostname MINGW64 ~
$ python

…坐在那里而不返回提示。

Python will not run in git bash (Windows). When I type python in the command line, it takes me to a blank line without saying that it has entered python 2.7.10 like its does in Powershell. It doesn’t give me an error message, but python just doesn’t run.

I have already made sure the environmental variables in PATH included c:\python27. What else can I check?


A session wherein this issue occurs looks like the following:

user@hostname MINGW64 ~
$ type python
python is /c/Python27/python

user@hostname MINGW64 ~
$ python

…sitting there without returning to the prompt.


回答 0

只需在Windows的git shell中输入- alias python='winpty python.exe',就可以了,您将拥有python可执行文件的别名。请享用

PS有关永久别名的添加,请参见下文,

cd ~
touch .bashrc

然后打开.bashrc,从上方添加命令并保存文件。您需要通过控制台创建文件,否则无法使用适当的名称保存文件。您还需要重新启动外壳以应用更改。

Just enter this in your git shell on windows – > alias python='winpty python.exe', that is all and you are going to have alias to the python executable. Enjoy

P.S. For permanent alias addition see below,

cd ~
touch .bashrc

then open .bashrc, add your command from above and save the file. You need to create the file through the console or you cannot save it with the proper name. You also need to restart the shell to apply the change.


回答 1

我在答案列表中没有看到下一个选项,但可以通过“ -i”键获得交互式提示:

$ python -i
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55)
Type "help", "copyright", "credits" or "license" for more information.
>>> 

I don’t see next option in a list of answers, but I can get interactive prompt with “-i” key:

$ python -i
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55)
Type "help", "copyright", "credits" or "license" for more information.
>>> 

回答 2

这是MSys2中的一个已知错误,该错误提供了Git Bash使用的终端。您可以通过运行不支持ncurses的Python构建或使用WinPTY解决该问题,方法如下:

要在mintty或Cygwin sshd中运行Windows控制台程序,请在命令行之前添加console.exe:

$ build/console.exe c:/Python27/python.exe
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 10 + 20
30
>>> exit()

用于msys预构建二进制文件可能与Git Bash一起使用。(如果发布此答案以来已经过了很长时间,请检查是否有较新的版本!)。


从Windows 2.7.1的Git开始,也尝试使用winpty c:Python27/python.exe;。WinPTY可能是现成的。

This is a known bug in MSys2, which provides the terminal used by Git Bash. You can work around it by running a Python build without ncurses support, or by using WinPTY, used as follows:

To run a Windows console program in mintty or Cygwin sshd, prepend console.exe to the command-line:

$ build/console.exe c:/Python27/python.exe
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 10 + 20
30
>>> exit()

The prebuilt binaries for msys are likely to work with Git Bash. (Do check whether there’s a newer version if significant time has passed since this answer was posted!).


As of Git for Windows 2.7.1, also try using winpty c:Python27/python.exe; WinPTY may be included out-of-the-box.


回答 3

我是Windows 10用户,我只接受默认值就已在系统中安装了GIT

阅读以上答案后,我得到了2个解决方案,并且这2个解决方案可完美地在GIT bash上运行,并帮助我在GIT bash 上执行Python语句。

我要附加3张我的GIT图像 bash终端的。第一个有问题,第二个有解决方案。

问题 -光标在按下python命令后才等待

解决方案1

winpty <path-to-python-installation-dir>/python.exeGIT bash终端上执行。

注意:请勿C:\Users\AdminGIT bash中使用类似路径样式,而应使用/C/Users/Admin

就我而言,我winpty /C/Users/SJV/Anaconda2/python.exeGIT bash 上执行了命令

或者,如果您不知道用户名,请执行winpty /C/Users/$USERNAME/Anaconda2/python.exe

解决方案2

只需输入即可python -i

谢谢。

I am windows 10 user and I have installed GIT in my system by just accepting the defaults.

After reading the above answers, I got 2 solutions for my own and these 2 solutions perfectly works on GIT bash and facilitates me to execute Python statements on GIT bash.

I am attaching 3 images of my GIT bash terminal. 1st with problem and the latter 2 as solutions.

PROBLEM – Cursor is just waiting after hitting python command

SOLUTION 1

Execute winpty <path-to-python-installation-dir>/python.exe on GIT bash terminal.

Note: Do not use C:\Users\Admin like path style in GIT bash, instead use /C/Users/Admin.

In my case, I executed winpty /C/Users/SJV/Anaconda2/python.exe command on GIT bash

Or if you do not know your username then execute winpty /C/Users/$USERNAME/Anaconda2/python.exe

SOLUTION 2

Just type python -i and that is it.

Thanks.


回答 4

尝试python -i代替python,这是一个游标。

Try python -i instead of python, it’s a cursor thing.


回答 5

除了@ Charles-Duffy的答案外,您还可以直接使用winpty,而无需安装/下载任何其他内容。赶紧跑winpty c:/Python27/python.exe。可以在Git \ usr \ bin中找到实用程序winpty.exe。我正在为Windows v2.7.1使用Git

@ Charles-Duffy的预编译二进制文件的版本为0.1.1(根据文件名),而随附的二进制文件的版本为0.2.2。

In addition to the answer of @Charles-Duffy, you can use winpty directly without installing/downloading anything extra. Just run winpty c:/Python27/python.exe. The utility winpty.exe can be found at Git\usr\bin. I’m using Git for Windows v2.7.1

The prebuilt binaries from @Charles-Duffy is version 0.1.1(according to the file name), while the included one is 0.2.2


回答 6

Git Bash解决方法-使用别名启动Python 2和Python 3

。(对我来说)这是在Win 10上直接从Git Bash直接运行Python(Python 2.7和Python 3.x)的最佳解决方案=>将别名添加到Git Bash用于的别名文件中。

Git Bash别名文件aliass.sh它位于:

C:\path where you installed Git\etc\profile.d\aliases.sh

1)(使用Atom等文字编辑器打开)aliases.sh

例如:在我的情况下,文件位于 C:\Software\Develop\Git\etc\profile.d\aliases.sh

2)为Python添加别名

就我而言python.exe安装在:

C:\Networking\Network Automation\Python 2.7\python.exe
C:\Networking\Network Automation\Python 3.7\python.exe

所以,你必须创建2别名,一个为Python 2我命名python2)和其他的Python 3我命名只是Python)的Git Bash使用Linux的文件结构,就需要改变“\”“/” ,如果你路径与我的示例网络自动化类似,您可以使用“”

“网络自动化”例如。

winpty是将调用可执行文件的魔术命令。

因此,在aliases.sh的开头添加这些行

alias python2='winpty C/Networking/"Network Automation"/"Python 2.7"/python.exe'
alias python='winpty C/Networking/"Network Automation"/"Python 3.7"/python.exe'

3)添加或修改其他别名(如果需要)

我还修改了ll别名,以显示所有文件并在人类可读的列表中:

alias ll='ls -lah'

4)保存aliases.sh文件


5)好!关闭并重新启动您的Git Bash

现在,您可以永久地从Git shell直接启动两个Python,只需编写

$ python ->启动Python 3

$ python2 ->启动Python 2

$ ll ->输入ls -lah快速显示您的详细文件列表

干杯,哈利

Git Bash Workaround- Launch Python 2 & Python 3 with aliases

HI. This is (for me) the best solution to run both Python (Python 2.7 and Python 3.x) directly from Git Bash on Win 10 => adding aliases into the aliases file that Git Bash uses for.

Git Bash aliases file is aliases.sh. It is located in:

C:\path where you installed Git\etc\profile.d\aliases.sh

1) Open (with a text editor like Atom or other) the aliases.sh

for ex: in my case the file is in C:\Software\Develop\Git\etc\profile.d\aliases.sh

2) Add your alias for Python

In my case the python.exe are installed in:

C:\Networking\Network Automation\Python 2.7\python.exe
C:\Networking\Network Automation\Python 3.7\python.exe

So you must create 2 aliases, one for Python 2 (I named python2) and the other for Python 3 (I named just python) Git Bash uses linux file structure so you need to change the “\” for “/” and if you have a path like my example Network Automation you put it with ” “

“Network Automation”, for ex.

winpty is the magic command that will call the executable.

So add these lines at the beginning of aliases.sh

alias python2='winpty C/Networking/"Network Automation"/"Python 2.7"/python.exe'
alias python='winpty C/Networking/"Network Automation"/"Python 3.7"/python.exe'

3) Add or Modify other aliases (if you want)

I modified also the ll alias to show all the files and in a human readable list:

alias ll='ls -lah'

4) Save the aliases.sh file


5) OK!!! close and relaunch your Git Bash

Now, permanently you could launch both Python directly from Git shell just writting

$ python -> launch Python 3

$ python2 -> launch Python 2

$ ll -> enters a ls -lah to quickly show your detailed file list

Cheers, Harry


回答 7

您可以从以下位置更改Git Bash快捷方式的目标:

"C:\Program Files\Git\git-bash.exe" --cd-to-home 

"C:\Program Files\Git\git-cmd.exe" --no-cd --command=usr/bin/bash.exe -l -i

这是ConEmu用于启动git bash(版本16)的方式。最新版本正常启动它,这就是我到达那里的方式…

You can change target for Git Bash shortcut from:

"C:\Program Files\Git\git-bash.exe" --cd-to-home 

to

"C:\Program Files\Git\git-cmd.exe" --no-cd --command=usr/bin/bash.exe -l -i

This is the way ConEmu used to start git bash (version 16). Recent version starts it normally and it’s how I got there…


回答 8

类型:“ winpty python”,它将起作用

gitbash在运行以python开头的任何命令时都会遇到一些问题。这也适用于任何python manage.py命令。始终以“ winpty python manage.py”开头至少这对我有用。运行Windows 10。

type: ‘winpty python’ and it will work

gitbash has some issues when running any command that starts with python. this goes for any python manage.py commands as well. Always start with ‘winpty python manage.py’ At least this is what works for me. Running Windows 10.


回答 9

除了@Vitaliy Terziev答案

请尝试touch .bash_profile,然后将别名添加到文件中。

In addition to @Vitaliy Terziev answer

try touch .bash_profile and then add alias into the file.


回答 10

2个解决方法,而不是解决方案:在我的Git Bash中,以下命令挂起,并且我没有得到提示:

% python

所以我只用:

% winpty python

正如上面的某些人所指出的,您还可以使用:

% python -i

2 workarounds, rather than a solution: In my Git Bash, following command hangs and I don’t get the prompt back:

% python

So I just use:

% winpty python

As some people have noted above, you can also use:

% python -i

2020-07-14: Git 2.27.0 has added optional experimental support for pseudo consoles, which allow running Python from the command line:

See attached session.


回答 11

我正在Windows 10上通过Visual Studio Code使用MINGW64,并尝试安装node-sass(需要python2)。我在Github上跟随了felixrieseberg / windows-build-tools#56,它解决了我的问题。

这是一个特例,但如果有人遇到相同的问题,我将在此发布:

npm --add-python-to-path='true' --debug install --global windows-build-tools

这会将python和其他必需的构建工具安装到%USERPROFILE%\.windows-build-tools\python27

I am using MINGW64 via Visual Studio Code on Windows 10 and trying to install node-sass (which requires python2). I followed felixrieseberg/windows-build-tools #56 on Github which solved my issue.

This is a special case, but I’m posting in case someone has the same problem:

npm --add-python-to-path='true' --debug install --global windows-build-tools

This installs python and other required build tools to %USERPROFILE%\.windows-build-tools\python27.


回答 12

对于以gitbash作为默认终端的vscode中的python版本3.7.3,我处理了一段时间,然后遵循@Vitaliy Terziev建议将别名添加到.bashrc中,但具有以下规范:

别名python =“’/ c / Users /我的用户名/AppData/Local/Programs/Python/Python37/python.exe”’

注意单引号和双引号的组合,因为“我的用户名”空格。

对我来说,“ winpty”无法解析vscode中的python路径。

For python version 3.7.3 in vscode with gitbash as the default terminal I was dealing with this for a while and then followed @Vitaliy Terziev advice of adding the alias to .bashrc but with the following specification:

alias python=’“/c/Users/my user name/AppData/Local/Programs/Python/Python37/python.exe”’

Notice the combination of single and double quotes because of “my user name” spaces.

For me, “winpty” couldn’t resolve python path in vscode.


回答 13

此问题的另一个示例是在Windows中使用git bash(MINGW64,Mintty)中的AWS Elastic Beanstalk命令行界面(awsebcli,eb cli)(使用git版本2.19.0.windows.1)。

我之所以发布此帖子,是因为我花了一段时间才能找到此处的eb-cli具体问题。

需要用户输入的命令(例如eb init或)似乎导致冻结/挂起。实际上,我想控制台未使用请求用户输入的文本进行更新。此外,eb config saveeb deploy仅在命令完成后才更新控制台文本,因此直到完成后我才能看到进度更新。

如在git for Windows发行说明(针对v2.19.0)和Xun Yang的答案中所述,一种解决方法是运行

winpty eb <command>(而不是eb <command>

正如本git Windows发行版中所建议的那样,替代方法可能是使用Windows本机控制台而不是mintty(在git安装过程中选择)。

Another example of this issue is using the AWS Elastic Beanstalk command line interface (awsebcli, eb cli) from the git bash (MINGW64, Mintty) in windows (using git version 2.19.0.windows.1).

I’m just posting this because it took me a while to end up here, searching for eb-cli specific issues.

Commands such as eb init or eb config save, which require user input, appear to cause a freeze/hang. In reality I guess the console is not updated with the text requesting user input. Moreover, eb deploy only updates the console text after the command has finished, so I don’t get to see progress updates until finished.

As mentioned in the git for windows release notes (for v2.19.0) and e.g. in Xun Yang’s answer, a workaround is to run

winpty eb <command> (instead of just eb <command>)

A alternative, as suggested in this git for windows issue, could be to use the windows native console instead of mintty (option during git installation).


回答 14

如前所述,上面为我工作的一个别名是以下别名:(我正在使用anaconda,因此首先找到python路径在哪里,然后将其添加到git bash上的别名中)。1.在anaconda终端上,我运行:where python 2.在git bash上,我运行:alias python='winpty "C:\ProgramData\Anaconda3\envs\your_env_name\python.exe"' 3.完成。Python是使用别名在git Bash内部定义的。

感谢(Vitaliy Terziev&hygull)的非常有益的回答。

The one worked for me is as mentioned earlier in these great answers above is the alias as follows: (I’m using anaconda, so first find where is the python path, then add it into the alias on git bash). 1. on anaconda terminal I run: where python 2. on git bash I run: alias python='winpty "C:\ProgramData\Anaconda3\envs\your_env_name\python.exe"' 3. Done. Python is defined inside the git Bash using the alias.

Thanks to (Vitaliy Terziev & hygull) for their very helpful answers.


回答 15

  1. python.exe -i可以,但是在发送“ ^ Z”(CTRL + Z)退出交互模式时遇到了问题。因此,winpty python.exe在Windows的Git Bash中使用似乎更好。

  2. 使用~/bin目录制作环绕/引用文件(如~/bin/python),该文件可在任何地方访问(您可以使用,如使用不同的版本参考~/bin/python37)。
    文件中的代码:

#!/usr/bin/env bash
# maybe declare env vars here like
# export PYTHONHOME=/c/Users/%USERNAME%/.python/Python36
# export PATH="${PATH}:/c/Users/%USERNAME%/.python/Python36"

# replace %USERNAME%,
# or use "~" instead of "/c/Users/%USERNAME%" if it works
winpty /c/Users/%USERNAME%/.python/Python36/python.exe ${@}

我只是不喜欢这些“魔术”别名,您总是忘记它的来源,有时在某些情况下会导致问题。

  1. 使用~/bin/python文件和-i参数:
#!/usr/bin/env bash
if [ -z "${@}" ]; then
    # empty args, use interactive mode
    /c/Users/%USERNAME%/.python/Python36/python.exe -i
else
    /c/Users/%USERNAME%/.python/Python36/python.exe ${@}
fi
  1. python.exe -i works but got issues in exiting from the interactive mode by sending “^Z” (CTRL+Z). So, seem better to use winpty python.exe in Git Bash for Windows.

  2. Use ~/bin directory to make a wrap/reference file (like ~/bin/python) which will be accessible everywhere (you may use different version reference like ~/bin/python37).
    Code inside the file:

#!/usr/bin/env bash
# maybe declare env vars here like
# export PYTHONHOME=/c/Users/%USERNAME%/.python/Python36
# export PATH="${PATH}:/c/Users/%USERNAME%/.python/Python36"

# replace %USERNAME%,
# or use "~" instead of "/c/Users/%USERNAME%" if it works
winpty /c/Users/%USERNAME%/.python/Python36/python.exe ${@}

I just don’t like these “magic” aliases which you’re always forgetting where it’s coming from, and sometimes leads to issues in some cases.

  1. Use ~/bin/python file and -i parameter:
#!/usr/bin/env bash
if [ -z "${@}" ]; then
    # empty args, use interactive mode
    /c/Users/%USERNAME%/.python/Python36/python.exe -i
else
    /c/Users/%USERNAME%/.python/Python36/python.exe ${@}
fi

回答 16

键入命令PY而不是Python。调用解释器(python.org)。

Type the command PY instead of Python. Invoking the Interpreter (python.org).


回答 17

看看这个答案:

Git Bash无法运行我的python文件吗?

Git Bash中的路径应设置为:

PATH=$PATH:/c/Python27/

Have a look at this answer:

Git Bash won’t run my python files?

the path in Git Bash should be set like this:

PATH=$PATH:/c/Python27/