Conda:直接从github安装/升级

问题:Conda:直接从github安装/升级

我可以使用conda从GitHub安装/升级软件包吗?

例如,pip我可以这样做:

pip install git+git://github.com/scrappy/scrappy@master

scrappy直接从masterGitHub中的分支安装。我可以用conda做一些等效的事情吗?

如果这不可能,那么用conda安装pip并使用pip管理此类本地安装是否有意义?

Can I install/upgrade packages from GitHub using conda?

For example, with pip I can do:

pip install git+git://github.com/scrappy/scrappy@master

to install scrappy directly from the master branch in GitHub. Can I do something equivalent with conda?

If this is not possible, would it make any sense to install pip with conda and manage such local installations with pip?


回答 0

现在,对此有了更好的支持conda-env。例如,您现在可以执行以下操作:

name: sample_env
channels:
dependencies:
   - requests
   - bokeh>=0.10.0
   - pip:
     - "--editable=git+https://github.com/pythonforfacebook/facebook-sdk.git@8c0d34291aaafec00e02eaa71cc2a242790a0fcc#egg=facebook_sdk-master"

它仍然在后台调用pip,但是您现在可以在一个environment.yml文件中统一conda和pip软件包的规范。

如果要使用此文件更新根环境,则需要将其保存到文件中(例如environment.yml),然后运行命令:conda env update -f environment.yml

您更可能想创建一个新环境:

conda env create -f environment.yml (已按评论中的假设进行了更改)

There’s better support for this now through conda-env. You can, for example, now do:

name: sample_env
channels:
dependencies:
   - requests
   - bokeh>=0.10.0
   - pip:
     - "--editable=git+https://github.com/pythonforfacebook/facebook-sdk.git@8c0d34291aaafec00e02eaa71cc2a242790a0fcc#egg=facebook_sdk-master"

It’s still calling pip under the covers, but you can now unify your conda and pip package specifications in a single environment.yml file.

If you wanted to update your root environment with this file, you would need to save this to a file (for example, environment.yml), then run the command: conda env update -f environment.yml.

It’s more likely that you would want to create a new environment:

conda env create -f environment.yml (changed as supposed in the comments)


回答 1

答案已经过时了。您只需要conda安装pip和git。然后您可以正常使用pip:

  1. 激活您的conda环境 source activate myenv

  2. conda install git pip

  3. pip install git+git://github.com/scrappy/scrappy@master

The answers are outdated. You simply have to conda install pip and git. Then you can use pip normally:

  1. Activate your conda environment source activate myenv

  2. conda install git pip

  3. pip install git+git://github.com/scrappy/scrappy@master


回答 2

conda不直接支持此功能,因为它是从二进制文件安装的,而git install是从源代码安装的。conda build确实支持从git构建的配方。另一方面,如果您要做的只是保持最新和最新的软件包,则在Anaconda中使用pip很好,或者替代地,setup.py develop对git克隆使用。

conda doesn’t support this directly because it installs from binaries, whereas git install would be from source. conda build does support recipes that are built from git. On the other hand, if all you want to do is keep up-to-date with the latest and greatest of a package, using pip inside of Anaconda is just fine, or alternately, use setup.py develop against a git clone.


回答 3

我在condas问题中找到了对此的参考。现在应该可以进行以下操作。

name: sample_env
channels:
dependencies:
   - requests
   - bokeh>=0.10.0
   - pip:
     - git+https://github.com/pythonforfacebook/facebook-sdk.git

I found a reference to this in condas issues. The following should now work.

name: sample_env
channels:
dependencies:
   - requests
   - bokeh>=0.10.0
   - pip:
     - git+https://github.com/pythonforfacebook/facebook-sdk.git

ImportError:DLL加载失败:%1不是有效的Win32应用程序。但是DLL在那里

问题:ImportError:DLL加载失败:%1不是有效的Win32应用程序。但是DLL在那里

我的情况非常类似于ImportError上的情况:DLL加载失败:%1不是有效的Win32应用程序,但是答案对我不起作用。

我的Python代码说:

import cv2

但是该行引发了此问题标题中显示的错误。

C:\lib\opencv在这台64位计算机上安装了OpenCV 。我正在使用64位Python。

我的PYTHONPATH变量:PYTHONPATH=C:\lib\opencv\build\python\2.7。该文件夹包含cv2.pyd所有内容。

我的PATH变量:Path=%OPENCV_DIR%\bin;...此文件夹包含39个DLL文件,例如opencv_core246d.dll

OPENCV_DIR具有以下值:OPENCV_DIR=C:\lib\opencv\build\x64\vc11

ImportError上的解决方案:DLL加载失败:%1不是有效的Win32应用程序,表示要向C:\opencv\build\bin\ReleaseWindows PATH环境变量添加新的opencv二进制路径()。但是,如上所示,C:\lib\opencv\build\x64\vc11\bin我的PATH中已经有OpenCV Binaries文件夹()。而且我的OpenCV安装没有任何Release文件夹(build / java下为空)。

关于出什么问题有什么想法吗?我可以告诉Python详细跟踪加载过程吗?究竟要寻找什么DLL?

谢谢,拉斯

编辑:

我只注意到,根据http://www.dependencywalker.com/中,cv2.pydC:\lib\opencv\build\python\2.7为32位,而我运行的机器和Python的是64位。可能是问题所在吗?如果是这样,我在哪里可以找到cv2.pyd的64位版本?

I have a situation very much like the one at ImportError: DLL load failed: %1 is not a valid Win32 application, but the answer there isn’t working for me.

My Python code says:

import cv2

But that line throws the error shown in the title of this question.

I have OpenCV installed in C:\lib\opencv on this 64-bit machine. I’m using 64-bit Python.

My PYTHONPATH variable: PYTHONPATH=C:\lib\opencv\build\python\2.7. This folder contains cv2.pyd and that’s all.

My PATH variable: Path=%OPENCV_DIR%\bin;... This folder contains 39 DLL files such as opencv_core246d.dll.

OPENCV_DIR has this value: OPENCV_DIR=C:\lib\opencv\build\x64\vc11.

The solution at ImportError: DLL load failed: %1 is not a valid Win32 application says to add “the new opencv binaries path (C:\opencv\build\bin\Release) to the Windows PATH environment variable”. But as shown above, I already have the OpenCV binaries folder (C:\lib\opencv\build\x64\vc11\bin) in my PATH. And my OpenCV installation doesn’t have any Release folders (except for an empty one under build/java).

Any ideas as to what’s going wrong? Can I tell Python to verbosely trace the loading process? Exactly what DLL’s is it looking for?

Thanks, Lars

EDIT:

I just noticed that, according to http://www.dependencywalker.com/, the cv2.pyd in C:\lib\opencv\build\python\2.7 is 32-bit, whereas the machine and the Python I’m running are 64-bit. Could that be the problem? And if so, where can I find a 64-bit version of cv2.pyd?


回答 0


回答 1

请检查您使用的python版本是否也是64位。如果没有,那可能就是问题所在。您将使用32位python版本,并且已为OPENCV库安装了64位二进制文​​件。

Please check if the python version you are using is also 64 bit. If not then that could be the issue. You would be using a 32 bit python version and would have installed a 64 bit binaries for the OPENCV library.


回答 2

哇,我发现了这个问题的另一种情况。以上都不起作用。最终,我使用python的功能来内省正在加载的内容。对于python 2.7,这意味着:

import imp
imp.find_module("cv2")

这在Anaconda DLL目录中打开了一个完全意外的“ cv2.pyd”文件,多次卸载/安装尝试均未涉及该文件。Python首先是在那儿寻找的,却找不到我的好安装。我删除了该cv2.pyd文件,然后再次尝试imp.find_module(“ cv2”),python立即找到了正确的文件,并且cv2开始工作。

因此,如果没有其他解决方案对您有用,请确保您使用python内省来查看python尝试加载的文件。

Wow, I found yet another case for this problem. None of the above worked. Eventually I used python’s ability to introspect what was being loaded. For python 2.7 this means:

import imp
imp.find_module("cv2")

This turned up a completely unexpected “cv2.pyd” file in an Anaconda DLL directory that wasn’t touched by multiple uninstall/install attempts. Python was looking there first and not finding my good installation. I deleted that cv2.pyd file and tried imp.find_module(“cv2”) again and python immediately found the right file and cv2 started working.

So if none of the other solutions work for you, make sure you use python introspection to see what file python is trying to load.


回答 3

就我而言,我有64位python,而lxml是错误的版本-我也应该一直使用x64版本。我通过在此处下载lxml的64位版本来解决此问题:

https://pypi.python.org/pypi/lxml/3.4.1

lxml-3.4.1.win-amd64-py2.7.exe

这是一个令人沮丧的问题的最简单答案。

In my case, I have 64bit python, and it was lxml that was the wrong version–I should have been using the x64 version of that as well. I solved this by downloading the 64-bit version of lxml here:

https://pypi.python.org/pypi/lxml/3.4.1

lxml-3.4.1.win-amd64-py2.7.exe

This was the simplest answer to a frustrating issue.


回答 4

我只是遇到了这个问题,原来是因为我使用的是x64版本的opencv文件。尝试了x86,它起作用了。

I just had this problem, it turns it was just because I was using x64 version of the opencv file. Tried the x86 and it worked.


回答 5

如果您的构建系统(在我的情况下为CMake)将文件从复制<name>.dll<name>.pyd,则如果原始文件实际上不是dll,则会出现此错误。就我而言,构建共享库已关闭,因此基础文件实际上是一个*.lib

我通过将pyd文件加载到DependencyWalker中并发现它无效而发现了此错误。

If your build-system (CMake in my case) copies the file from <name>.dll to <name>.pyd, you will get this error if the original file wasn’t actually a dll. In my case, building shared libraries got switched off, so the underlying file was actually a *.lib.

I discovered this error by loading the pyd file in DependencyWalker and finding that it wasn’t valid.


回答 6

我有同样的问题。这是我所做的:

  1. 我从这里下载pywin32 Wheel文件,然后

  2. 我卸载了pywin32模块。要卸载,请在命令提示符中执行以下命令。

    pip uninstall pywin32

  3. 然后,我重新安装了pywin32。要安装它,请在pywin32 wheel文件所在的目录中打开命令提示符。然后执行以下命令。

    pip install <Name of the wheel file with extension> 车轮文件将类似于:piwin32-XXX-cpXX-none-win32.whl

它为我解决了问题。您可能还想尝试一下。希望它也对您有用。

I had the same problem. Here’s what I did:

  1. I downloaded pywin32 Wheel file from here, then

  2. I uninstalled the pywin32 module. To uninstall execute the following command in Command Prompt.

    pip uninstall pywin32

  3. Then, I reinstalled pywin32. To install it, open the Command Prompt in the same directory where the pywin32 wheel file lies. Then execute the following command.

    pip install <Name of the wheel file with extension> Wheel file will be like: piwin32-XXX-cpXX-none-win32.whl

It solvs the problem for me. You may also like to give it a try. Hope it work for you as well.


回答 7

cv2.pyd/opencv/build/python/2.7/x86文件夹而不是从/x64文件夹复制文件到C:/Python27/Lib/site-packeges。我按照此处提供的其余说明进行操作。

由其他人添加,未经验证:我还复制了文件 cv2.pyd到folder C:/Python27/Lib/site-packages/cv2。有用。

I copied cv2.pyd file from /opencv/build/python/2.7/x86 folder instead of from /x64 folder to C:/Python27/Lib/site-packeges. I followed rest of the instructions provided here.

Added by someone else, not verified: I also copy file cv2.pyd to folder C:/Python27/Lib/site-packages/cv2. It works.


回答 8

对我来说,问题是我在同一个 Eclipse项目中使用了不同版本的Python 。我的设置与“ 项目属性”和“ 运行配置” Python版本不一致。

项目>属性> PyDev中,将解释器设置为Python2.7.11。

“运行配置”>“解释器”中,我正在使用“默认解释器”。将其更改为Python 2.7.11可解决此问题。

For me the problem was that I was using different versions of Python in the same Eclipse project. My setup was not consistent with the Project Properties and the Run Configuration Python versions.

In Project > Properties > PyDev, I had the Interpreter set to Python2.7.11.

In Run Configurations > Interpreter, I was using the Default Interpreter. Changing it to Python 2.7.11 fixed the problem.


回答 9

当我使用32位Windows Installer在系统上卸载并重新安装其他版本的2.7.x Python时,遇到了相同的问题。我的大多数导入语句都出现相同的错误。我卸载了新安装的Python,然后下载了64位Windows安装程序,然后再次重新安装了Python,它可以正常工作。希望对您有帮助。

I faced the same issue when I uninstalled and reinstalled a different version of 2.7.x of Python on my system using a 32 bit Windows Installer. I got the same error on most of my import statements. I uninstalled the newly installed Python and downloaded a 64 bit Windows installer and reinstalled Python again and it worked. Hope this helps you.


回答 10

所以我在Windows下安装vtk时遇到问题(由于我使用python 3.7,到目前为止,仅适用于较旧的python版本,没有可用的二进制文件pip install vtk无法正常工作)

我确实在cmd中编写了python:

Python 3.7.3 on win32

所以我现在知道我的python 3.7.3在32位上运行。

然后,我在下载了正确的车轮 VTK-8.2.0-cp37-cp37m-win32.whl

接下来,我安装了该轮子:

pip install VTK-8.2.0-cp37-cp37m-win32.whl

然后,我对其进行了测试并成功运行:

python
import vtk

So I had problems installing vtk under windows (as I use python 3.7 there is no binary available so far just for older python versions pip install vtk is not working)

I did wrote python in my cmd:

Python 3.7.3 on win32

So I now know I have python 3.7.3 runing on a 32 bit.

I then downloaded the correct wheel at VTK‑8.2.0‑cp37‑cp37m‑win32.whl

Next I instlled that wheel:

pip install VTK-8.2.0-cp37-cp37m-win32.whl

Then I tested it and it worked:

python
import vtk

回答 11

更新numpy。

pip install numpy --upgrade

为我工作!

Update numpy.

pip install numpy --upgrade

Work for me!!


回答 12

首先,我cv2.pyd从复制/opencv/build/python/2.7/x86C:/Python27/Lib/site-packeges。错误是

“ RuntimeError:模块是根据API版本9编译的,但此版本的numpy是7”

然后我安装了numpy-1.8.0-win32-superpack-python2.7.exeopencv,并且工作正常。

>>> import cv2
>>> print cv2.__version__
2.4.13

First I copied cv2.pyd from /opencv/build/python/2.7/x86 to C:/Python27/Lib/site-packeges. The error was

“RuntimeError: module compiled against API version 9 but this version of numpy is 7”

Then I installed numpy-1.8.0-win32-superpack-python2.7.exe and opencv works fine.

>>> import cv2
>>> print cv2.__version__
2.4.13

回答 13

您可以opencv官方非官方站点进行安装。

如果使用,请参考问题和问题Anaconda

You can install opencv from official or unofficial sites.

Refer to this question and this issue if you are using Anaconda.


回答 14

  1. 请确保您已安装python 2.7.12或更低版本,否则您肯定会收到此错误。
  2. 如果操作系统为64位,请确保已安装64位Oracle客户端。
  3. 确保用于Python 2.7的Microsoft Visual C ++编译器对于64位Os为64位,对于32位为32位。注意:-如果您的操作系统是64位,则安装所有64位软件包;如果操作系统是32位,则安装32位软件包。
  1. Please make sure that you have installed python 2.7.12 or below version otherwise you will get this error definitely.
  2. Make sure Oracle client is 64 bit installed if OS is 64 Bit.
  3. Make sure Microsoft Visual C++ Compiler for Python 2.7 is 64 for bit for 64 bit Os or 32 bit for 32 bit. Note:- IF ur OS is 64 bit install all package of 64 bit or if Os is 32 bit install 32 bit package.

回答 15

它有一个非常简单的解决方案。安装后的opencv 地方

cv2.pydC:\opencv\build\python\2.7\ **x64**C:\Python27\Lib\site-packages

代替,cv2.pydC:\opencv\build\python\2.7\ **x86**C:\Python27\Lib\site-packages

It has a very simple solution. After installing opencv place

cv2.pyd from C:\opencv\build\python\2.7\ **x64** to C:\Python27\Lib\site-packages

instead of, place cv2.pyd from C:\opencv\build\python\2.7\ **x86** to C:\Python27\Lib\site-packages


回答 16

尝试导入MySQLdb时出现此错误。

对我有用的是卸载Python,然后重新安装。

安装npm(https://www.npmjs.com/get-npm)后出现错误。它所做的一件事是即使我已经安装了Python,也要安装它。

I got this error when trying to import MySQLdb.

What worked for me was to uninstall Python and then reinstall it.

I got the error after installing npm (https://www.npmjs.com/get-npm). One thing it did was install Python even though I already had it.


回答 17

这对我有用。我尝试了不同的方法,但这是我最好的解决方案。

打开命令提示符并键入以下内容; pip install opencv-python。(确保您的互联网已打开)。之后,请尝试再次导入。

This has worked for me. I have tried different methods but this was my best solution.

Open command prompt and type the following; pip install opencv-python. (make sure your internet is on). after that try importing it again.


回答 18

这个跟我一起工作

pip install -- pywin32==227

This one worked with me

pip install -- pywin32==227

回答 19

我找到了解决方案,也许您可​​以尝试使用cmd窗口而不是anaconda提示窗口来开始您的第一笔测试。

I found the solution, maybe you can try to use the cmd window rather than the anaconda prompt window to start you first scrapy test.


在Python中处理字符串中的转义序列

问题:在Python中处理字符串中的转义序列

有时,当我从文件或用户那里得到输入时,我会得到一个带有转义序列的字符串。我想以与Python处理字符串文字中的转义序列相同的方式来处理转义序列

例如,假设myString定义为:

>>> myString = "spam\\neggs"
>>> print(myString)
spam\neggs

我想要一个process执行此操作的函数(我称之为):

>>> print(process(myString))
spam
eggs

该函数可以处理Python中的所有转义序列(在上面的链接的表格中列出),这一点很重要。

Python是否具有执行此操作的功能?

Sometimes when I get input from a file or the user, I get a string with escape sequences in it. I would like to process the escape sequences in the same way that Python processes escape sequences in string literals.

For example, let’s say myString is defined as:

>>> myString = "spam\\neggs"
>>> print(myString)
spam\neggs

I want a function (I’ll call it process) that does this:

>>> print(process(myString))
spam
eggs

It’s important that the function can process all of the escape sequences in Python (listed in a table in the link above).

Does Python have a function to do this?


回答 0

正确的做法是使用“字符串转义”代码对字符串进行解码。

>>> myString = "spam\\neggs"
>>> decoded_string = bytes(myString, "utf-8").decode("unicode_escape") # python3 
>>> decoded_string = myString.decode('string_escape') # python2
>>> print(decoded_string)
spam
eggs

不要使用AST或eval。使用字符串编解码器更加安全。

The correct thing to do is use the ‘string-escape’ code to decode the string.

>>> myString = "spam\\neggs"
>>> decoded_string = bytes(myString, "utf-8").decode("unicode_escape") # python3 
>>> decoded_string = myString.decode('string_escape') # python2
>>> print(decoded_string)
spam
eggs

Don’t use the AST or eval. Using the string codecs is much safer.


回答 1

unicode_escape 总的来说不起作用

事实证明,string_escapeor unicode_escape解决方案通常无法正常工作-尤其是在存在实际Unicode的情况下,它不能正常工作。

如果您可以确定每个非ASCII字符都会被转义(并且请记住,前128个字符以外的任何字符都是非ASCII),unicode_escape将为您做正确的事。但是,如果您的字符串中已经有任何文字上的非ASCII字符,则会出错。

unicode_escape从根本上来说是设计用来将字节转换为Unicode文本。但是在许多地方(例如Python源代码),源数据已经是Unicode文本。

唯一可以正常工作的方法是首先将文本编码为字节。UTF-8是所有文本的明智编码,因此应该可以使用,对吧?

以下示例是Python 3中的示例,因此字符串文字更清晰,但在Python 2和3上,存在相同的问题,但表现形式略有不同。

>>> s = 'naïve \\t test'
>>> print(s.encode('utf-8').decode('unicode_escape'))
naïve   test

好吧,那是错误的。

建议使用编解码器将文本解码为文本的新方法是codecs.decode直接调用。有帮助吗?

>>> import codecs
>>> print(codecs.decode(s, 'unicode_escape'))
naïve   test

一点也不。(此外,以上是Python 2上的UnicodeError。)

unicode_escape编解码器,尽管它的名字,原来假设所有非ASCII字节拉丁-1(ISO-8859-1)编码。因此,您必须这样做:

>>> print(s.encode('latin-1').decode('unicode_escape'))
naïve    test

但这太可怕了。这将您限制为256个Latin-1字符,就好像根本没有发明Unicode一样!

>>> print('Ernő \\t Rubik'.encode('latin-1').decode('unicode_escape'))
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0151'
in position 3: ordinal not in range(256)

添加正则表达式以解决问题

(令人惊讶的是,我们现在没有两个问题。)

我们需要做的只是将unicode_escape解码器应用于我们确定为ASCII文本的内容。特别是,我们可以确保仅将其应用于有效的Python转义序列,这些序列必须保证为ASCII文本。

计划是,我们将使用正则表达式查找转义序列,并使用函数作为参数以re.sub将其替换为未转义的值。

import re
import codecs

ESCAPE_SEQUENCE_RE = re.compile(r'''
    ( \\U........      # 8-digit hex escapes
    | \\u....          # 4-digit hex escapes
    | \\x..            # 2-digit hex escapes
    | \\[0-7]{1,3}     # Octal escapes
    | \\N\{[^}]+\}     # Unicode characters by name
    | \\[\\'"abfnrtv]  # Single-character escapes
    )''', re.UNICODE | re.VERBOSE)

def decode_escapes(s):
    def decode_match(match):
        return codecs.decode(match.group(0), 'unicode-escape')

    return ESCAPE_SEQUENCE_RE.sub(decode_match, s)

然后:

>>> print(decode_escapes('Ernő \\t Rubik'))
Ernő     Rubik

unicode_escape doesn’t work in general

It turns out that the string_escape or unicode_escape solution does not work in general — particularly, it doesn’t work in the presence of actual Unicode.

If you can be sure that every non-ASCII character will be escaped (and remember, anything beyond the first 128 characters is non-ASCII), unicode_escape will do the right thing for you. But if there are any literal non-ASCII characters already in your string, things will go wrong.

unicode_escape is fundamentally designed to convert bytes into Unicode text. But in many places — for example, Python source code — the source data is already Unicode text.

The only way this can work correctly is if you encode the text into bytes first. UTF-8 is the sensible encoding for all text, so that should work, right?

The following examples are in Python 3, so that the string literals are cleaner, but the same problem exists with slightly different manifestations on both Python 2 and 3.

>>> s = 'naïve \\t test'
>>> print(s.encode('utf-8').decode('unicode_escape'))
naïve   test

Well, that’s wrong.

The new recommended way to use codecs that decode text into text is to call codecs.decode directly. Does that help?

>>> import codecs
>>> print(codecs.decode(s, 'unicode_escape'))
naïve   test

Not at all. (Also, the above is a UnicodeError on Python 2.)

The unicode_escape codec, despite its name, turns out to assume that all non-ASCII bytes are in the Latin-1 (ISO-8859-1) encoding. So you would have to do it like this:

>>> print(s.encode('latin-1').decode('unicode_escape'))
naïve    test

But that’s terrible. This limits you to the 256 Latin-1 characters, as if Unicode had never been invented at all!

>>> print('Ernő \\t Rubik'.encode('latin-1').decode('unicode_escape'))
UnicodeEncodeError: 'latin-1' codec can't encode character '\u0151'
in position 3: ordinal not in range(256)

Adding a regular expression to solve the problem

(Surprisingly, we do not now have two problems.)

What we need to do is only apply the unicode_escape decoder to things that we are certain to be ASCII text. In particular, we can make sure only to apply it to valid Python escape sequences, which are guaranteed to be ASCII text.

The plan is, we’ll find escape sequences using a regular expression, and use a function as the argument to re.sub to replace them with their unescaped value.

import re
import codecs

ESCAPE_SEQUENCE_RE = re.compile(r'''
    ( \\U........      # 8-digit hex escapes
    | \\u....          # 4-digit hex escapes
    | \\x..            # 2-digit hex escapes
    | \\[0-7]{1,3}     # Octal escapes
    | \\N\{[^}]+\}     # Unicode characters by name
    | \\[\\'"abfnrtv]  # Single-character escapes
    )''', re.UNICODE | re.VERBOSE)

def decode_escapes(s):
    def decode_match(match):
        return codecs.decode(match.group(0), 'unicode-escape')

    return ESCAPE_SEQUENCE_RE.sub(decode_match, s)

And with that:

>>> print(decode_escapes('Ernő \\t Rubik'))
Ernő     Rubik

回答 2

python 3的实际正确答案:

>>> import codecs
>>> myString = "spam\\neggs"
>>> print(codecs.escape_decode(bytes(myString, "utf-8"))[0].decode("utf-8"))
spam
eggs
>>> myString = "naïve \\t test"
>>> print(codecs.escape_decode(bytes(myString, "utf-8"))[0].decode("utf-8"))
naïve    test

有关的详细信息codecs.escape_decode

  • codecs.escape_decode 是一个逐字节解码器
  • codecs.escape_decode解码ascii转义序列,例如:b"\\n"-> b"\n"b"\\xce"-> b"\xce"
  • codecs.escape_decode 不需要或不需要了解字节对象的编码,但是转义字节的编码应与对象其余部分的编码匹配。

背景:

The actually correct and convenient answer for python 3:

>>> import codecs
>>> myString = "spam\\neggs"
>>> print(codecs.escape_decode(bytes(myString, "utf-8"))[0].decode("utf-8"))
spam
eggs
>>> myString = "naïve \\t test"
>>> print(codecs.escape_decode(bytes(myString, "utf-8"))[0].decode("utf-8"))
naïve    test

Details regarding codecs.escape_decode:

  • codecs.escape_decode is a bytes-to-bytes decoder
  • codecs.escape_decode decodes ascii escape sequences, such as: b"\\n" -> b"\n", b"\\xce" -> b"\xce".
  • codecs.escape_decode does not care or need to know about the byte object’s encoding, but the encoding of the escaped bytes should match the encoding of the rest of the object.

Background:

  • @rspeer is correct: unicode_escape is the incorrect solution for python3. This is because unicode_escape decodes escaped bytes, then decodes bytes to unicode string, but receives no information regarding which codec to use for the second operation.
  • @Jerub is correct: avoid the AST or eval.
  • I first discovered codecs.escape_decode from this answer to “how do I .decode(‘string-escape’) in Python3?”. As that answer states, that function is currently not documented for python 3.

回答 3

ast.literal_eval函数将关闭,但是它将期望该字符串先被正确引用。

当然反斜杠Python的解释依赖于字符串的方式引用(""VS r""VS u"",三引号等),所以你可能想包装在合适的报价的用户输入和传递给literal_eval。将其包装在引号中还可以防止literal_eval返回数字,元组,字典等。

如果用户键入您打算在字符串周围使用的引号引起来,事情可能仍然会变得棘手。

The ast.literal_eval function comes close, but it will expect the string to be properly quoted first.

Of course Python’s interpretation of backslash escapes depends on how the string is quoted ("" vs r"" vs u"", triple quotes, etc) so you may want to wrap the user input in suitable quotes and pass to literal_eval. Wrapping it in quotes will also prevent literal_eval from returning a number, tuple, dictionary, etc.

Things still might get tricky if the user types unquoted quotes of the type you intend to wrap around the string.


回答 4

这是一个不好的方法,但是当我尝试解释在字符串参数中传递的转义八进制时,它对我有用。

input_string = eval('b"' + sys.argv[1] + '"')

值得一提的是,eval和ast.literal_eval之间存在区别(eval更加不安全)。请参阅使用python的eval()与ast.literal_eval()吗?

This is a bad way of doing it, but it worked for me when trying to interpret escaped octals passed in a string argument.

input_string = eval('b"' + sys.argv[1] + '"')

It’s worth mentioning that there is a difference between eval and ast.literal_eval (eval being way more unsafe). See Using python’s eval() vs. ast.literal_eval()?


回答 5

下面的代码应该适用于\ n,要求将其显示在字符串上。

import string

our_str = 'The String is \\n, \\n and \\n!'
new_str = string.replace(our_str, '/\\n', '/\n', 1)
print(new_str)

Below code should work for \n is required to be displayed on the string.

import string

our_str = 'The String is \\n, \\n and \\n!'
new_str = string.replace(our_str, '/\\n', '/\n', 1)
print(new_str)

读取文件数据而不将其保存在Flask中

问题:读取文件数据而不将其保存在Flask中

我正在编写我的第一个烧瓶应用程序。我正在处理文件上传,基本上我想要的是读取上传文件的数据/内容而不保存它,然后将其打印在结果页面上。是的,我假设用户总是上载文本文件。

这是我正在使用的简单上传功能:

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        file = request.files['file']
        if file:
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            a = 'file uploaded'

    return render_template('upload.html', data = a)

现在,我正在保存文件,但是我需要的是一个’a’变量来包含文件的内容/数据。

I am writing my first flask application. I am dealing with file uploads, and basically what I want is to read the data/content of the uploaded file without saving it and then print it on the resulting page. Yes, I am assuming that the user uploads a text file always.

Here is the simple upload function i am using:

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        file = request.files['file']
        if file:
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            a = 'file uploaded'

    return render_template('upload.html', data = a)

Right now, I am saving the file, but what I need is that ‘a’ variable to contain the content/data of the file .. any ideas?


回答 0

FileStorage包含stream字段。该对象必须扩展IO或文件对象,因此它必须包含read和其他类似方法。FileStorage还扩展了stream字段对象属性,因此您可以使用file.read()代替file.stream.read()。您也可以使用save带有dst参数as的参数StringIO或其他IO或文件对象来复制FileStorage.stream到另一个IO或文件对象。

请参阅文档:http : //flask.pocoo.org/docs/api/#flask.Request.fileshttp://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage

FileStorage contains stream field. This object must extend IO or file object, so it must contain read and other similar methods. FileStorage also extend stream field object attributes, so you can just use file.read() instead file.stream.read(). Also you can use save argument with dst parameter as StringIO or other IO or file object to copy FileStorage.stream to another IO or file object.

See documentation: http://flask.pocoo.org/docs/api/#flask.Request.files and http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage.


回答 1

如果您要使用标准的Flask素材-如果上传的文件大小> 500kb,则无法避免保存临时文件。如果小于500kb,则将使用“ BytesIO”,它将文件内容存储在内存中;如果大于500kb,则将内容存储在TemporaryFile()中(如werkzeug文档中所述)。在这两种情况下,您的脚本都将阻塞,直到收到全部上传的文件为止。

我发现解决此问题的最简单方法是:

1)创建自己的类似于文件的IO类,在其中对传入数据进行所有处理

2)在您的脚本中,使用您自己的脚本覆盖Request类:

class MyRequest( Request ):
  def _get_file_stream( self, total_content_length, content_type, filename=None, content_length=None ):
    return MyAwesomeIO( filename, 'w' )

3)用您自己的替换Flask的request_class:

app.request_class = MyRequest

4)去喝点啤酒:)

If you want to use standard Flask stuff – there’s no way to avoid saving a temporary file if the uploaded file size is > 500kb. If it’s smaller than 500kb – it will use “BytesIO”, which stores the file content in memory, and if it’s more than 500kb – it stores the contents in TemporaryFile() (as stated in the werkzeug documentation). In both cases your script will block until the entirety of uploaded file is received.

The easiest way to work around this that I have found is:

1) Create your own file-like IO class where you do all the processing of the incoming data

2) In your script, override Request class with your own:

class MyRequest( Request ):
  def _get_file_stream( self, total_content_length, content_type, filename=None, content_length=None ):
    return MyAwesomeIO( filename, 'w' )

3) Replace Flask’s request_class with your own:

app.request_class = MyRequest

4) Go have some beer :)


回答 2

我试图做完全相同的事情,打开一个文本文件(实际上是熊猫的CSV文件)。不想复制它,只想打开它。WTF表单有一个不错的文件浏览器,但是随后它打开了文件并制作了一个临时文件,该文件以内存流的形式呈现。稍微做些工作,

form = UploadForm() 
 if form.validate_on_submit(): 
      filename = secure_filename(form.fileContents.data.filename)  
      filestream =  form.fileContents.data 
      filestream.seek(0)
      ef = pd.read_csv( filestream  )
      sr = pd.DataFrame(ef)  
      return render_template('dataframe.html',tables=[sr.to_html(justify='center, classes='table table-bordered table-hover')],titles = [filename], form=form) 

I was trying to do the exact same thing, open a text file (a CSV for Pandas actually). Don’t want to make a copy of it, just want to open it. The form-WTF has a nice file browser, but then it opens the file and makes a temporary file, which it presents as a memory stream. With a little work under the hood,

form = UploadForm() 
 if form.validate_on_submit(): 
      filename = secure_filename(form.fileContents.data.filename)  
      filestream =  form.fileContents.data 
      filestream.seek(0)
      ef = pd.read_csv( filestream  )
      sr = pd.DataFrame(ef)  
      return render_template('dataframe.html',tables=[sr.to_html(justify='center, classes='table table-bordered table-hover')],titles = [filename], form=form) 

回答 3

我分享我的解决方案(假设所有内容都已配置为可以连接到烧瓶中的Google存储桶)

from google.cloud import storage

@app.route('/upload/', methods=['POST'])
def upload():
    if request.method == 'POST':
        # FileStorage object wrapper
        file = request.files["file"]                    
        if file:
            os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = app.config['GOOGLE_APPLICATION_CREDENTIALS']
            bucket_name = "bucket_name" 
            storage_client = storage.Client()
            bucket = storage_client.bucket(bucket_name)
            # Upload file to Google Bucket
            blob = bucket.blob(file.filename) 
            blob.upload_from_string(file.read())

我的帖子

直指烧瓶中的Google Bucket

I share my solution (assuming everything is already configured to connect to google bucket in flask)

from google.cloud import storage

@app.route('/upload/', methods=['POST'])
def upload():
    if request.method == 'POST':
        # FileStorage object wrapper
        file = request.files["file"]                    
        if file:
            os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = app.config['GOOGLE_APPLICATION_CREDENTIALS']
            bucket_name = "bucket_name" 
            storage_client = storage.Client()
            bucket = storage_client.bucket(bucket_name)
            # Upload file to Google Bucket
            blob = bucket.blob(file.filename) 
            blob.upload_from_string(file.read())

My post

Direct to Google Bucket in flask


回答 4

万一我们想将内存文件转储到磁盘上。可以使用此代码

  if isinstanceof(obj,SpooledTemporaryFile):
    obj.rollover()

In case we want to dump the in memory file to disk. This code can be used

  if isinstanceof(obj,SpooledTemporaryFile):
    obj.rollover()


回答 5

我们只是做了:

import io
from pathlib import Path

    def test_my_upload(self, accept_json):
        """Test my uploads endpoint for POST."""
        data = {
            "filePath[]": "/tmp/bin",
            "manifest[]": (io.StringIO(str(Path(__file__).parent /
                                           "path_to_file/npmlist.json")).read(),
                           'npmlist.json'),
        }
        headers = {
            'a': 'A',
            'b': 'B'
        }
        res = self.client.post(api_route_for('/test'),
                               data=data,
                               content_type='multipart/form-data',
                               headers=headers,
                               )
        assert res.status_code == 200

We simply did:

import io
from pathlib import Path

    def test_my_upload(self, accept_json):
        """Test my uploads endpoint for POST."""
        data = {
            "filePath[]": "/tmp/bin",
            "manifest[]": (io.StringIO(str(Path(__file__).parent /
                                           "path_to_file/npmlist.json")).read(),
                           'npmlist.json'),
        }
        headers = {
            'a': 'A',
            'b': 'B'
        }
        res = self.client.post(api_route_for('/test'),
                               data=data,
                               content_type='multipart/form-data',
                               headers=headers,
                               )
        assert res.status_code == 200

回答 6

在功能上

def handleUpload():
    if 'photo' in request.files:
        photo = request.files['photo']
        if photo.filename != '':      
            image = request.files['photo']  
            image_string = base64.b64encode(image.read())
            image_string = image_string.decode('utf-8')
            #use this to remove b'...' to get raw string
            return render_template('handleUpload.html',filestring = image_string)
    return render_template('upload.html')

在html文件中

<html>
<head>
    <title>Simple file upload using Python Flask</title>
</head>
<body>
    {% if filestring %}
      <h1>Raw image:</h1>
      <h1>{{filestring}}</h1>
      <img src="data:image/png;base64, {{filestring}}" alt="alternate" />.
    {% else %}
      <h1></h1>
    {% endif %}
</body>

in function

def handleUpload():
    if 'photo' in request.files:
        photo = request.files['photo']
        if photo.filename != '':      
            image = request.files['photo']  
            image_string = base64.b64encode(image.read())
            image_string = image_string.decode('utf-8')
            #use this to remove b'...' to get raw string
            return render_template('handleUpload.html',filestring = image_string)
    return render_template('upload.html')

in html file

<html>
<head>
    <title>Simple file upload using Python Flask</title>
</head>
<body>
    {% if filestring %}
      <h1>Raw image:</h1>
      <h1>{{filestring}}</h1>
      <img src="data:image/png;base64, {{filestring}}" alt="alternate" />.
    {% else %}
      <h1></h1>
    {% endif %}
</body>


对一组值进行排序[关闭]

问题:对一组值进行排序[关闭]

我有这样的价值观:

set(['0.000000000', '0.009518000', '10.277200999', '0.030810999', '0.018384000', '4.918560000'])
set(['4.918859000', '0.060758000', '4.917336999', '0.003949999', '0.013945000', '10.281522000', '0.025082999'])  

我想按升序对每个值进行排序set。我不想在组之间进行排序,而是在每个组中进行排序。

I have values like this:

set(['0.000000000', '0.009518000', '10.277200999', '0.030810999', '0.018384000', '4.918560000'])
set(['4.918859000', '0.060758000', '4.917336999', '0.003949999', '0.013945000', '10.281522000', '0.025082999'])  

I want to sort the values in each set in increasing order. I don’t want to sort between the sets, but the values in each set.


回答 0

来自评论:

我想对每个集合进行排序。

这很简单。对于任何集合s(或其他任何可迭代的对象),以排序顺序sorted(s)返回的元素列表s

>>> s = set(['0.000000000', '0.009518000', '10.277200999', '0.030810999', '0.018384000', '4.918560000'])
>>> sorted(s)
['0.000000000', '0.009518000', '0.018384000', '0.030810999', '10.277200999', '4.918560000']

请注意,这sorted是给您一个list,而不是一个set。这是因为在数学几乎每种编程语言中,集合的全部要点*都是无序的:集合{1, 2}{2, 1}是同一集合。


您可能真的不想将这些元素排序为字符串,而是将其排序为数字(因此,4.918560000将在10.277200999之前而不是之后)。

最好的解决方案是最有可能首先将数字存储为数字而不是字符串。但是,如果没有,您只需要使用一个key函数:

>>> sorted(s, key=float)
['0.000000000', '0.009518000', '0.018384000', '0.030810999', '4.918560000', '10.277200999']

有关更多信息,请参阅官方文档中的Sorting HOWTO


*请参阅注释以了解exceptions情况。

From a comment:

I want to sort each set.

That’s easy. For any set s (or anything else iterable), sorted(s) returns a list of the elements of s in sorted order:

>>> s = set(['0.000000000', '0.009518000', '10.277200999', '0.030810999', '0.018384000', '4.918560000'])
>>> sorted(s)
['0.000000000', '0.009518000', '0.018384000', '0.030810999', '10.277200999', '4.918560000']

Note that sorted is giving you a list, not a set. That’s because the whole point of a set, both in mathematics and in almost every programming language,* is that it’s not ordered: the sets {1, 2} and {2, 1} are the same set.


You probably don’t really want to sort those elements as strings, but as numbers (so 4.918560000 will come before 10.277200999 rather than after).

The best solution is most likely to store the numbers as numbers rather than strings in the first place. But if not, you just need to use a key function:

>>> sorted(s, key=float)
['0.000000000', '0.009518000', '0.018384000', '0.030810999', '4.918560000', '10.277200999']

For more information, see the Sorting HOWTO in the official docs.


* See the comments for exceptions.


如何在Python中从文件名替换(或剥离)扩展名?

问题:如何在Python中从文件名替换(或剥离)扩展名?

Python中是否有内置函数可以替换(或删除,无论如何)文件名的扩展名(如果有扩展名)?

例:

print replace_extension('/home/user/somefile.txt', '.jpg')

在我的示例中:/home/user/somefile.txt将变为/home/user/somefile.jpg

我不知道这是否重要,但是我正在编写的SCons模块需要它。(所以也许有一些我可以使用的SCons特定功能?)

我想要一些干净的东西。对所有出现.txt在字符串中的字符串进行简单的字符串替换显然并不干净。(如果我的文件名是,这将失败somefile.txt.txt.txt

Is there a built-in function in Python that would replace (or remove, whatever) the extension of a filename (if it has one) ?

Example:

print replace_extension('/home/user/somefile.txt', '.jpg')

In my example: /home/user/somefile.txt would become /home/user/somefile.jpg

I don’t know if it matters, but I need this for a SCons module I’m writing. (So perhaps there is some SCons specific function I can use ?)

I’d like something clean. Doing a simple string replacement of all occurrences of .txt within the string is obviously not clean. (This would fail if my filename is somefile.txt.txt.txt)


回答 0

试试os.path.splitext它应该做你想要的。

import os
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg'

Try os.path.splitext it should do what you want.

import os
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg'

回答 1

扩展AnaPana的答案,即如何使用pathlib(Python> = 3.4)删除扩展:

>>> from pathlib import Path

>>> filename = Path('/some/path/somefile.txt')

>>> filename_wo_ext = filename.with_suffix('')

>>> filename_replace_ext = filename.with_suffix('.jpg')

>>> print(filename)
/some/path/somefile.ext    

>>> print(filename_wo_ext)
/some/path/somefile

>>> print(filename_replace_ext)
/some/path/somefile.jpg

Expanding on AnaPana’s answer, how to remove an extension using pathlib (Python >= 3.4):

>>> from pathlib import Path

>>> filename = Path('/some/path/somefile.txt')

>>> filename_wo_ext = filename.with_suffix('')

>>> filename_replace_ext = filename.with_suffix('.jpg')

>>> print(filename)
/some/path/somefile.ext    

>>> print(filename_wo_ext)
/some/path/somefile

>>> print(filename_replace_ext)
/some/path/somefile.jpg

回答 2

就像@jethro所说的那样,splitext是一种很好的方法。但是在这种情况下,您可以很容易地自己拆分它,因为扩展名必须是最后一个句点之后的文件名的一部分:

filename = '/home/user/somefile.txt'
print( filename.rsplit( ".", 1 )[ 0 ] )
# '/home/user/somefile'

rsplit告诉Python从字符串的右边开始执行字符串分割,而告诉Python 1最多执行一个分割(例如'foo.bar.baz'-> [ 'foo.bar', 'baz' ])。由于rsplit将始终返回一个非空数组,因此我们可以安全地对其进行索引0以获取文件名减去扩展名。

As @jethro said, splitext is the neat way to do it. But in this case, it’s pretty easy to split it yourself, since the extension must be the part of the filename coming after the final period:

filename = '/home/user/somefile.txt'
print( filename.rsplit( ".", 1 )[ 0 ] )
# '/home/user/somefile'

The rsplit tells Python to perform the string splits starting from the right of the string, and the 1 says to perform at most one split (so that e.g. 'foo.bar.baz' -> [ 'foo.bar', 'baz' ]). Since rsplit will always return a non-empty array, we may safely index 0 into it to get the filename minus the extension.


回答 3

我更喜欢以下使用str.rsplit()的单线方法:

my_filename.rsplit('.', 1)[0] + '.jpg'

例:

>>> my_filename = '/home/user/somefile.txt'
>>> my_filename.rsplit('.', 1)
>>> ['/home/user/somefile', 'txt']

I prefer the following one-liner approach using str.rsplit():

my_filename.rsplit('.', 1)[0] + '.jpg'

Example:

>>> my_filename = '/home/user/somefile.txt'
>>> my_filename.rsplit('.', 1)
>>> ['/home/user/somefile', 'txt']

回答 4

对于Python> = 3.4:

from pathlib import Path

filename = '/home/user/somefile.txt'

p = Path(filename)
new_filename = p.parent.joinpath(p.stem + '.jpg') # PosixPath('/home/user/somefile.jpg')
new_filename_str = str(new_filename) # '/home/user/somefile.jpg'

For Python >= 3.4:

from pathlib import Path

filename = '/home/user/somefile.txt'

p = Path(filename)
new_filename = p.parent.joinpath(p.stem + '.jpg') # PosixPath('/home/user/somefile.jpg')
new_filename_str = str(new_filename) # '/home/user/somefile.jpg'

回答 5

处理多个扩展

如果您有多个扩展名,则此单行代码使用pathlibstr.replace有效对待:

删除/扩展扩展名

>>> from pathlib import Path
>>> p = Path("/path/to/myfile.tar.gz")
>>> str(p).replace("".join(p.suffixes), "")
'/path/to/myfile'

替换扩展名

>>> p = Path("/path/to/myfile.tar.gz")
>>> new_ext = ".jpg"
>>> str(p).replace("".join(p.suffixes), new_ext)
'/path/to/myfile.jpg'

如果您还需要pathlib对象输出,那么显然可以将行换行Path()

>>> Path(str(p).replace("".join(p.suffixes), ""))
PosixPath('/path/to/myfile')

将所有内容包装在一个函数中

from pathlib import Path
from typing import Union

PathLike = Union[str, Path]


def replace_ext(path: PathLike, new_ext: str = "") -> Path:
    extensions = "".join(Path(path).suffixes)
    return Path(str(p).replace(extensions, new_ext))


p = Path("/path/to/myfile.tar.gz")
new_ext = ".jpg"

assert replace_ext(p, new_ext) == Path('/path/to/myfile.jpg')
assert replace_ext(str(p), new_ext) == Path('/path/to/myfile.jpg')
assert replace_ext(p) == Path('/path/to/myfile')

Handling multiple extensions

In the case where you have multiple extensions this one-liner using pathlib and str.replace works a treat:

Remove/strip extensions

>>> from pathlib import Path
>>> p = Path("/path/to/myfile.tar.gz")
>>> str(p).replace("".join(p.suffixes), "")
'/path/to/myfile'

Replace extensions

>>> p = Path("/path/to/myfile.tar.gz")
>>> new_ext = ".jpg"
>>> str(p).replace("".join(p.suffixes), new_ext)
'/path/to/myfile.jpg'

If you also want a pathlib object output then you can obviously wrap the line in Path()

>>> Path(str(p).replace("".join(p.suffixes), ""))
PosixPath('/path/to/myfile')

Wrapping it all up in a function

from pathlib import Path
from typing import Union

PathLike = Union[str, Path]


def replace_ext(path: PathLike, new_ext: str = "") -> Path:
    extensions = "".join(Path(path).suffixes)
    return Path(str(p).replace(extensions, new_ext))


p = Path("/path/to/myfile.tar.gz")
new_ext = ".jpg"

assert replace_ext(p, new_ext) == Path('/path/to/myfile.jpg')
assert replace_ext(str(p), new_ext) == Path('/path/to/myfile.jpg')
assert replace_ext(p) == Path('/path/to/myfile')

回答 6

另一种方法是使用该str.rpartition(sep)方法。

例如:

filename = '/home/user/somefile.txt'
(prefix, sep, suffix) = filename.rpartition('.')

new_filename = prefix + '.jpg'

print new_filename

Another way to do is to use the str.rpartition(sep) method.

For example:

filename = '/home/user/somefile.txt'
(prefix, sep, suffix) = filename.rpartition('.')

new_filename = prefix + '.jpg'

print new_filename

如何为多个环境自定义requirements.txt?

问题:如何为多个环境自定义requirements.txt?

我有两个分支,开发和生产。每个都有依赖关系,其中一些是不同的。开发指向自身在开发中的依赖项。生产同样如此。我需要部署到Heroku,它期望每个分支的依赖性都在一个名为“ requirements.txt”的文件中。

最好的组织方式是什么?

我想到的是:

  • 维护单独的需求文件,每个分支中一个(必须在频繁合并中生存!)
  • 告诉Heroku我要使用哪个需求文件(环境变量?)
  • 编写部署脚本(创建临时分支,修改需求文件,提交,部署,删除临时分支)

I have two branches, Development and Production. Each has dependencies, some of which are different. Development points to dependencies that are themselves in development. Likewise for Production. I need to deploy to Heroku which expects each branch’s dependencies in a single file called ‘requirements.txt’.

What is the best way to organize?

What I’ve thought of:

  • Maintain separate requirements files, one in each branch (must survive frequent merges!)
  • Tell Heroku which requirements file I want to use (environment variable?)
  • Write deploy scripts (create temp branch, modify requirements file, commit, deploy, delete temp branch)

回答 0

您可以级联需求文件,并使用“ -r”标志告诉pip将一个文件的内容包含在另一个文件中。您可以将需求分解成模块化的文件夹层次结构,如下所示:

`-- django_project_root
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   `-- prod.txt
`-- requirements.txt

文件的内容如下所示:

common.txt:

# Contains requirements common to all environments
req1==1.0
req2==1.0
req3==1.0
...

dev.txt:

# Specifies only dev-specific requirements
# But imports the common ones too
-r common.txt
dev_req==1.0
...

prod.txt:

# Same for prod...
-r common.txt
prod_req==1.0
...

在Heroku之外,您现在可以设置如下环境:

pip install -r requirements/dev.txt

要么

pip install -r requirements/prod.txt

由于Heroku在项目根目录中专门查找“ requirements.txt”,因此应仅镜像prod,如下所示:

requirements.txt:

# Mirrors prod
-r requirements/prod.txt

You can cascade your requirements files and use the “-r” flag to tell pip to include the contents of one file inside another. You can break out your requirements into a modular folder hierarchy like this:

`-- django_project_root
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   `-- prod.txt
`-- requirements.txt

The files’ contents would look like this:

common.txt:

# Contains requirements common to all environments
req1==1.0
req2==1.0
req3==1.0
...

dev.txt:

# Specifies only dev-specific requirements
# But imports the common ones too
-r common.txt
dev_req==1.0
...

prod.txt:

# Same for prod...
-r common.txt
prod_req==1.0
...

Outside of Heroku, you can now setup environments like this:

pip install -r requirements/dev.txt

or

pip install -r requirements/prod.txt

Since Heroku looks specifically for “requirements.txt” at the project root, it should just mirror prod, like this:

requirements.txt:

# Mirrors prod
-r requirements/prod.txt

回答 1

今天发布原始问题和答案时不存在的可行选择是使用pipenv而不是pip管理依赖项。

使用pipenv,不再需要像pip一样手动管理两个单独的需求文件,而是通过命令行上的交互来管理开发和生产包本身。

要安装用于生产和开发的软件包:

pipenv install <package>

要仅为开发环境安装软件包:

pipenv install <package> --dev

通过这些命令,pipenv在两个文件(Pipfile和Pipfile.lock)中存储和管理环境配置。Heroku当前的Python buildpack本机支持pipenv,如果存在Pipfile.lock而不是requirements.txt,它将从Pipfile.lock进行配置。

有关该工具的完整文档,请参见pipenv链接。

A viable option today which didn’t exist when the original question and answer was posted is to use pipenv instead of pip to manage dependencies.

With pipenv, manually managing two separate requirement files like with pip is no longer necessary, and instead pipenv manages the development and production packages itself via interactions on the command line.

To install a package for use in both production and development:

pipenv install <package>

To install a package for the development environment only:

pipenv install <package> --dev

Via those commands, pipenv stores and manages the environment configuration in two files (Pipfile and Pipfile.lock). Heroku’s current Python buildpack natively supports pipenv and will configure itself from Pipfile.lock if it exists instead of requirements.txt.

See the pipenv link for full documentation of the tool.


回答 2

如果您的要求是能够在同一台计算机上的环境之间进行切换,则可能有必要为需要切换到的每个环境创建不同的virtualenv文件夹。

python3 -m venv venv_dev
source venv_dev/bin/activate
pip install -r pip/common.txt
pip install -r pip/dev.txt
exit
python3 -m venv venv_prod
source venv_prod/bin/activate
pip install -r pip/common.txt
exit
source venv_dev/bin/activate
# now we are in dev environment so your code editor and build systems will work.

# let's install a new dev package:
# pip install awesome
# pip freeze -r pip/temp.txt
# find that package, put it into pip/dev.txt
# rm pip/temp.txt

# pretty cumbersome, but it works. 

If your requirement is to be able to switch between environments on the same machine, it may be necessary to create different virtualenv folders for each environment you need to switch to.

python3 -m venv venv_dev
source venv_dev/bin/activate
pip install -r pip/common.txt
pip install -r pip/dev.txt
exit
python3 -m venv venv_prod
source venv_prod/bin/activate
pip install -r pip/common.txt
exit
source venv_dev/bin/activate
# now we are in dev environment so your code editor and build systems will work.

# let's install a new dev package:
# pip install awesome
# pip freeze -r pip/temp.txt
# find that package, put it into pip/dev.txt
# rm pip/temp.txt

# pretty cumbersome, but it works. 

在Python 3中禁止/打印不带b’前缀的字节

问题:在Python 3中禁止/打印不带b’前缀的字节

只需发布此内容,以便稍后查找,因为它总是让我感到困惑:

$ python3.2
Python 3.2 (r32:88445, Oct 20 2012, 14:09:50) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import curses
>>> print(curses.version)
b'2.2'
>>> print(str(curses.version))
b'2.2'
>>> print(curses.version.encode('utf-8'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'bytes' object has no attribute 'encode'
>>> print(str(curses.version).encode('utf-8'))
b"b'2.2'"

问题:如何bytes在Python 3中打印不带b'前缀的二进制()字符串?

Just posting this so I can search for it later, as it always seems to stump me:

$ python3.2
Python 3.2 (r32:88445, Oct 20 2012, 14:09:50) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import curses
>>> print(curses.version)
b'2.2'
>>> print(str(curses.version))
b'2.2'
>>> print(curses.version.encode('utf-8'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'bytes' object has no attribute 'encode'
>>> print(str(curses.version).encode('utf-8'))
b"b'2.2'"

As question: how to print a binary (bytes) string in Python 3, without the b' prefix?


回答 0

用途decode

print(curses.version.decode())
# 2.2

Use decode:

print(curses.version.decode())
# 2.2

回答 1

如果字节已经使用适当的字符编码;您可以直接打印它们:

sys.stdout.buffer.write(data)

要么

nwritten = os.write(sys.stdout.fileno(), data)  # NOTE: it may write less than len(data) bytes

If the bytes use an appropriate character encoding already; you could print them directly:

sys.stdout.buffer.write(data)

or

nwritten = os.write(sys.stdout.fileno(), data)  # NOTE: it may write less than len(data) bytes

回答 2

如果我们看一下的源代码bytes.__repr__,看起来就像b''是将烘焙到方法中一样。

最明显的解决方法是b''从结果中手动切片repr()

>>> x = b'\x01\x02\x03\x04'

>>> print(repr(x))
b'\x01\x02\x03\x04'

>>> print(repr(x)[2:-1])
\x01\x02\x03\x04

If we take a look at the source for bytes.__repr__, it looks as if the b'' is baked into the method.

The most obvious workaround is to manually slice off the b'' from the resulting repr():

>>> x = b'\x01\x02\x03\x04'

>>> print(repr(x))
b'\x01\x02\x03\x04'

>>> print(repr(x)[2:-1])
\x01\x02\x03\x04

回答 3

如果数据采用UTF-8兼容格式,则可以将字节转换为字符串。

>>> import curses
>>> print(str(curses.version, "utf-8"))
2.2

如果数据尚不兼容UTF-8,则可以选择先转换为十六进制。例如,当数据是实际的原始字节时。

from binascii import hexlify
from codecs import encode  # alternative
>>> print(hexlify(b"\x13\x37"))
b'1337'
>>> print(str(hexlify(b"\x13\x37"), "utf-8"))
1337
>>>> print(str(encode(b"\x13\x37", "hex"), "utf-8"))
1337

If the data is in an UTF-8 compatible format, you can convert the bytes to a string.

>>> import curses
>>> print(str(curses.version, "utf-8"))
2.2

Optionally convert to hex first, if the data is not already UTF-8 compatible. E.g. when the data are actual raw bytes.

from binascii import hexlify
from codecs import encode  # alternative
>>> print(hexlify(b"\x13\x37"))
b'1337'
>>> print(str(hexlify(b"\x13\x37"), "utf-8"))
1337
>>>> print(str(encode(b"\x13\x37", "hex"), "utf-8"))
1337

导入模块中全局变量的可见性

问题:导入模块中全局变量的可见性

我在使用Python脚本导入模块时遇到了一些麻烦。我将尽力描述错误,为什么会遇到错误以及为什么要使用这种特殊方法来解决我的问题(我将在稍后描述):

假设我有一个模块,其中定义了一些实用程序函数/类,这些函数/类引用在此辅助模块将导入到的命名空间中定义的实体(让“ a”是这样的实体):

模块1:

def f():
    print a

然后,我有了主程序,其中定义了“ a”,我要将这些实用程序导入其中:

import module1
a=3
module1.f()

执行该程序将触发以下错误:

Traceback (most recent call last):
  File "Z:\Python\main.py", line 10, in <module>
    module1.f()
  File "Z:\Python\module1.py", line 3, in f
    print a
NameError: global name 'a' is not defined

过去(两天前,d’uh)曾提出类似的问题,并提出了几种解决方案,但是我真的不认为这些符合我的要求。这是我的特定情况:

我正在尝试制作一个Python程序,该程序连接到MySQL数据库服务器并使用GUI显示/修改数据。为了简洁起见,我在一个单独的文件中定义了一堆与MySQL相关的辅助/实用程序功能。但是它们都有一个公共变量,该变量是我最初实用程序模块中定义的,并且是MySQLdb模块中的游标对象。后来我意识到,游标对象(用于与db服务器通信的对象)应该在主模块中定义,以便主模块和导入到其中的所有对象都可以访问该对象。

最终结果将是这样的:

utilities_module.py:

def utility_1(args):
    code which references a variable named "cur"
def utility_n(args):
    etcetera

而我的主要模块:

program.py:

import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor()  #cur is defined!
from utilities_module import *

然后,一旦我尝试调用任何实用程序函数,就会触发上述“未定义全局名称”错误。

一个特别的建议是在实用程序文件中有一个“ from program import cur”语句,例如:

utilities_module.py:

from program import cur
#rest of function definitions

program.py:

import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor()  #cur is defined!
from utilities_module import *

但这是循环导入或类似的操作,最重要的是,它也崩溃了。所以我的问题是:

我该如何在主模块中定义的“ cur”对象对导入到其中的辅助功能可见?

如果您将解决方案发布在其他位置,则感谢您的宝贵时间和最深切的歉意。我只是自己找不到答案,而且我的书中没有其他花招。

I’ve run into a bit of a wall importing modules in a Python script. I’ll do my best to describe the error, why I run into it, and why I’m tying this particular approach to solve my problem (which I will describe in a second):

Let’s suppose I have a module in which I’ve defined some utility functions/classes, which refer to entities defined in the namespace into which this auxiliary module will be imported (let “a” be such an entity):

module1:

def f():
    print a

And then I have the main program, where “a” is defined, into which I want to import those utilities:

import module1
a=3
module1.f()

Executing the program will trigger the following error:

Traceback (most recent call last):
  File "Z:\Python\main.py", line 10, in <module>
    module1.f()
  File "Z:\Python\module1.py", line 3, in f
    print a
NameError: global name 'a' is not defined

Similar questions have been asked in the past (two days ago, d’uh) and several solutions have been suggested, however I don’t really think these fit my requirements. Here’s my particular context:

I’m trying to make a Python program which connects to a MySQL database server and displays/modifies data with a GUI. For cleanliness sake, I’ve defined the bunch of auxiliary/utility MySQL-related functions in a separate file. However they all have a common variable, which I had originally defined inside the utilities module, and which is the cursor object from MySQLdb module. I later realised that the cursor object (which is used to communicate with the db server) should be defined in the main module, so that both the main module and anything that is imported into it can access that object.

End result would be something like this:

utilities_module.py:

def utility_1(args):
    code which references a variable named "cur"
def utility_n(args):
    etcetera

And my main module:

program.py:

import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor()  #cur is defined!
from utilities_module import *

And then, as soon as I try to call any of the utilities functions, it triggers the aforementioned “global name not defined” error.

A particular suggestion was to have a “from program import cur” statement in the utilities file, such as this:

utilities_module.py:

from program import cur
#rest of function definitions

program.py:

import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor()  #cur is defined!
from utilities_module import *

But that’s cyclic import or something like that and, bottom line, it crashes too. So my question is:

How in hell can I make the “cur” object, defined in the main module, visible to those auxiliary functions which are imported into it?

Thanks for your time and my deepest apologies if the solution has been posted elsewhere. I just can’t find the answer myself and I’ve got no more tricks in my book.


回答 0

Python中的全局变量是模块的全局变量,而不是所有模块的全局变量。(许多人对此感到困惑,因为在C语言中,除非您明确创建全局变量,否则所有实现文件中的全局变量都是相同的static。)

有多种解决方法,具体取决于您的实际用例。


在走这条路之前,请问自己这是否真的需要是全球性的。也许您真的想要一个带有f实例方法的类,而不仅仅是一个自由函数?然后,您可以执行以下操作:

import module1
thingy1 = module1.Thingy(a=3)
thingy1.f()

如果您确实确实想要一个全局变量,但是它只是供您使用module1,请在该模块中进行设置。

import module1
module1.a=3
module1.f()

另一方面,如果a由许多模块共享,则将其放置在其他位置,并让每个人都将其导入:

import shared_stuff
import module1
shared_stuff.a = 3
module1.f()

…并且,在module1.py中:

import shared_stuff
def f():
    print shared_stuff.a

from除非变量打算是一个常量,否则不要使用导入。from shared_stuff import a会创建一个新a变量,初始化为shared_stuff.a导入时所引用的变量,并且该新a变量将不受分配的影响shared_stuff.a


或者,在极少数情况下,您确实确实需要它在任何地方都具有真正的全局性(例如内置),将其添加到内置模块中。确切的细节在Python 2.x和3.x之间有所不同。在3.x中,它的工作方式如下:

import builtins
import module1
builtins.a = 3
module1.f()

Globals in Python are global to a module, not across all modules. (Many people are confused by this, because in, say, C, a global is the same across all implementation files unless you explicitly make it static.)

There are different ways to solve this, depending on your actual use case.


Before even going down this path, ask yourself whether this really needs to be global. Maybe you really want a class, with f as an instance method, rather than just a free function? Then you could do something like this:

import module1
thingy1 = module1.Thingy(a=3)
thingy1.f()

If you really do want a global, but it’s just there to be used by module1, set it in that module.

import module1
module1.a=3
module1.f()

On the other hand, if a is shared by a whole lot of modules, put it somewhere else, and have everyone import it:

import shared_stuff
import module1
shared_stuff.a = 3
module1.f()

… and, in module1.py:

import shared_stuff
def f():
    print shared_stuff.a

Don’t use a from import unless the variable is intended to be a constant. from shared_stuff import a would create a new a variable initialized to whatever shared_stuff.a referred to at the time of the import, and this new a variable would not be affected by assignments to shared_stuff.a.


Or, in the rare case that you really do need it to be truly global everywhere, like a builtin, add it to the builtin module. The exact details differ between Python 2.x and 3.x. In 3.x, it works like this:

import builtins
import module1
builtins.a = 3
module1.f()

回答 1

解决方法是,您可以考虑像这样在外层设置环境变量。

main.py:

import os
os.environ['MYVAL'] = str(myintvariable)

mymodule.py:

import os

myval = None
if 'MYVAL' in os.environ:
    myval = os.environ['MYVAL']

作为额外的预防措施,请在模块内部未定义MYVAL的情况下进行处理。

As a workaround, you could consider setting environment variables in the outer layer, like this.

main.py:

import os
os.environ['MYVAL'] = str(myintvariable)

mymodule.py:

import os

myval = None
if 'MYVAL' in os.environ:
    myval = os.environ['MYVAL']

As an extra precaution, handle the case when MYVAL is not defined inside the module.


回答 2

函数使用其定义模块的全局变量。a = 3例如,应该设置而不是set module1.a = 3。因此,如果要cur用作全局输入utilities_module,请设置utilities_module.cur

更好的解决方案:不要使用全局变量。将所需的变量传递到需要它的函数中,或者创建一个类将所有数据捆绑在一起,并在初始化实例时传递它。

A function uses the globals of the module it’s defined in. Instead of setting a = 3, for example, you should be setting module1.a = 3. So, if you want cur available as a global in utilities_module, set utilities_module.cur.

A better solution: don’t use globals. Pass the variables you need into the functions that need it, or create a class to bundle all the data together, and pass it when initializing the instance.


回答 3

这篇文章只是我遇到的Python行为的观察。如果您做的事情与我在下面做的相同,则上面阅读的建议可能对您不起作用。

即,我有一个包含全局/共享变量的模块(如上所述):

#sharedstuff.py

globaltimes_randomnode=[]
globalist_randomnode=[]

然后,我有一个主要模块,用于导入共享内容:

import sharedstuff as shared

以及实际填充这些数组的其他一些模块。这些由主模块调用。当退出这些其他模块时,我可以清楚地看到已填充了阵列。但是,当在主模块中重新读取它们时,它们为空。这对我来说很奇怪(嗯,我是Python的新手)。但是,当我将主模块中的sharedstuff.py导入方式更改为:

from globals import *

它有效(填充了数组)。

只是在说’

This post is just an observation for Python behaviour I encountered. Maybe the advices you read above don’t work for you if you made the same thing I did below.

Namely, I have a module which contains global/shared variables (as suggested above):

#sharedstuff.py

globaltimes_randomnode=[]
globalist_randomnode=[]

Then I had the main module which imports the shared stuff with:

import sharedstuff as shared

and some other modules that actually populated these arrays. These are called by the main module. When exiting these other modules I can clearly see that the arrays are populated. But when reading them back in the main module, they were empty. This was rather strange for me (well, I am new to Python). However, when I change the way I import the sharedstuff.py in the main module to:

from globals import *

it worked (the arrays were populated).

Just sayin’


回答 4

解决此特定问题的最简单方法是在模块内添加另一个功能,该功能会将光标存储在模块的全局变量中。然后所有其他功能也可以使用它。

模块1:

cursor = None

def setCursor(cur):
    global cursor
    cursor = cur

def method(some, args):
    global cursor
    do_stuff(cursor, some, args)

主程序:

import module1

cursor = get_a_cursor()
module1.setCursor(cursor)
module1.method()

The easiest solution to this particular problem would have been to add another function within the module that would have stored the cursor in a variable global to the module. Then all the other functions could use it as well.

module1:

cursor = None

def setCursor(cur):
    global cursor
    cursor = cur

def method(some, args):
    global cursor
    do_stuff(cursor, some, args)

main program:

import module1

cursor = get_a_cursor()
module1.setCursor(cursor)
module1.method()

回答 5

由于全局变量是特定于模块的,因此可以将以下函数添加到所有导入的模块中,然后将其用于:

  • 将单数变量(以字典格式)添加为这些变量的全局变量
  • 将您的模块全局变量传递给它。

addglobals = lambda x:globals()。update(x)

然后,您需要传递当前的全局变量是:

导入模块

module.addglobals(globals())

Since globals are module specific, you can add the following function to all imported modules, and then use it to:

  • Add singular variables (in dictionary format) as globals for those
  • Transfer your main module globals to it .

addglobals = lambda x: globals().update(x)

Then all you need to pass on current globals is:

import module

module.addglobals(globals())


回答 6

由于我在上面的答案中没有看到它,因此我想我将添加一个简单的解决方法,global_dict即向需要调用模块全局变量的函数添加一个参数,然后在调用时将dict传递给该函数。例如:

# external_module
def imported_function(global_dict=None):
    print(global_dict["a"])


# calling_module
a = 12
from external_module import imported_function
imported_function(global_dict=globals())

>>> 12

Since I haven’t seen it in the answers above, I thought I would add my simple workaround, which is just to add a global_dict argument to the function requiring the calling module’s globals, and then pass the dict into the function when calling; e.g:

# external_module
def imported_function(global_dict=None):
    print(global_dict["a"])


# calling_module
a = 12
from external_module import imported_function
imported_function(global_dict=globals())

>>> 12

回答 7

这样做的OOP方法是使模块成为类,而不是一组未绑定的方法。然后,您可以使用__init__或setter方法来设置来自调用方的变量,以用于模块方法中。

The OOP way of doing this would be to make your module a class instead of a set of unbound methods. Then you could use __init__ or a setter method to set the variables from the caller for use in the module methods.


索引所有*除外* python中的一项

问题:索引所有*除外* python中的一项

有没有一种简单的方法来索引列表(或数组,或其他任何东西)中特定索引之外的所有元素?例如,

  • mylist[3] 将把该物品退回第3位

  • milist[~3] 将返回整个列表,除了3

Is there a simple way to index all elements of a list (or array, or whatever) except for a particular index? E.g.,

  • mylist[3] will return the item in position 3

  • milist[~3] will return the whole list except for 3


回答 0

对于列表,您可以使用列表组合。例如,要制作不含第3个元素b的副本a

a = range(10)[::-1]                       # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
b = [x for i,x in enumerate(a) if i!=3]   # [9, 8, 7, 5, 4, 3, 2, 1, 0]

这是非常通用的方法,可用于所有可迭代对象,包括numpy数组。如果您替换[]()b将是一个迭代器,而非列表。

或者,您可以通过以下方式就地完成此操作pop

a = range(10)[::-1]     # a = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
a.pop(3)                # a = [9, 8, 7, 5, 4, 3, 2, 1, 0]

numpy中,您可以使用布尔索引来做到这一点:

a = np.arange(9, -1, -1)     # a = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
b = a[np.arange(len(a))!=3]  # b = array([9, 8, 7, 5, 4, 3, 2, 1, 0])

通常,这比上面列出的列表理解要快得多。

For a list, you could use a list comp. For example, to make b a copy of a without the 3rd element:

a = range(10)[::-1]                       # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
b = [x for i,x in enumerate(a) if i!=3]   # [9, 8, 7, 5, 4, 3, 2, 1, 0]

This is very general, and can be used with all iterables, including numpy arrays. If you replace [] with (), b will be an iterator instead of a list.

Or you could do this in-place with pop:

a = range(10)[::-1]     # a = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
a.pop(3)                # a = [9, 8, 7, 5, 4, 3, 2, 1, 0]

In numpy you could do this with a boolean indexing:

a = np.arange(9, -1, -1)     # a = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
b = a[np.arange(len(a))!=3]  # b = array([9, 8, 7, 5, 4, 3, 2, 1, 0])

which will, in general, be much faster than the list comprehension listed above.


回答 1

>>> l = range(1,10)
>>> l
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[:2] 
[1, 2]
>>> l[3:]
[4, 5, 6, 7, 8, 9]
>>> l[:2] + l[3:]
[1, 2, 4, 5, 6, 7, 8, 9]
>>> 

也可以看看

解释Python的切片符号

>>> l = range(1,10)
>>> l
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[:2] 
[1, 2]
>>> l[3:]
[4, 5, 6, 7, 8, 9]
>>> l[:2] + l[3:]
[1, 2, 4, 5, 6, 7, 8, 9]
>>> 

See also

Explain Python’s slice notation


回答 2

我发现的最简单的方法是:

mylist[:x]+mylist[x+1:]

这将产生mylist没有index的元素x

The simplest way I found was:

mylist[:x] + mylist[x+1:]

that will produce your mylist without the element at index x.

Example

mylist = [0, 1, 2, 3, 4, 5]
x = 3
mylist[:x] + mylist[x+1:]

Result produced

mylist = [0, 1, 2, 4, 5]

回答 3

如果您使用的是numpy,则我认为最接近的是使用蒙版

>>> import numpy as np
>>> arr = np.arange(1,10)
>>> mask = np.ones(arr.shape,dtype=bool)
>>> mask[5]=0
>>> arr[mask]
array([1, 2, 3, 4, 5, 7, 8, 9])

如果itertools没有,可以达到类似的效果numpy

>>> from itertools import compress
>>> arr = range(1,10)
>>> mask = [1]*len(arr)
>>> mask[5]=0
>>> list(compress(arr,mask))
[1, 2, 3, 4, 5, 7, 8, 9]

If you are using numpy, the closest, I can think of is using a mask

>>> import numpy as np
>>> arr = np.arange(1,10)
>>> mask = np.ones(arr.shape,dtype=bool)
>>> mask[5]=0
>>> arr[mask]
array([1, 2, 3, 4, 5, 7, 8, 9])

Something similar can be achieved using itertools without numpy

>>> from itertools import compress
>>> arr = range(1,10)
>>> mask = [1]*len(arr)
>>> mask[5]=0
>>> list(compress(arr,mask))
[1, 2, 3, 4, 5, 7, 8, 9]

回答 4

使用np.delete!它实际上并没有删除任何内容

例:

import numpy as np
a = np.array([[1,4],[5,7],[3,1]])                                       

# a: array([[1, 4],
#           [5, 7],
#           [3, 1]])

ind = np.array([0,1])                                                   

# ind: array([0, 1])

# a[ind]: array([[1, 4],
#                [5, 7]])

all_except_index = np.delete(a, ind, axis=0)                                              
# all_except_index: array([[3, 1]])

# a: (still the same): array([[1, 4],
#                             [5, 7],
#                             [3, 1]])

Use np.delete ! It does not actually delete anything inplace

Example:

import numpy as np
a = np.array([[1,4],[5,7],[3,1]])                                       

# a: array([[1, 4],
#           [5, 7],
#           [3, 1]])

ind = np.array([0,1])                                                   

# ind: array([0, 1])

# a[ind]: array([[1, 4],
#                [5, 7]])

all_except_index = np.delete(a, ind, axis=0)                                              
# all_except_index: array([[3, 1]])

# a: (still the same): array([[1, 4],
#                             [5, 7],
#                             [3, 1]])

回答 5

我将提供一种功能(不变)的方法。

  1. 做到这一点的标准和简单方法是使用切片:

    index_to_remove = 3
    data = [*range(5)]
    new_data = data[:index_to_remove] + data[index_to_remove + 1:]
    
    print(f"data: {data}, new_data: {new_data}")

    输出:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
  2. 使用清单理解:

    data = [*range(5)]
    new_data = [v for i, v in enumerate(data) if i != index_to_remove]
    
    print(f"data: {data}, new_data: {new_data}") 

    输出:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
  3. 使用过滤功能:

    index_to_remove = 3
    data = [*range(5)]
    new_data = [*filter(lambda i: i != index_to_remove, data)]

    输出:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
  4. 使用遮罩。屏蔽由标准库中的itertools.compress函数提供:

    from itertools import compress
    
    index_to_remove = 3
    data = [*range(5)]
    mask = [1] * len(data)
    mask[index_to_remove] = 0
    new_data = [*compress(data, mask)]
    
    print(f"data: {data}, mask: {mask}, new_data: {new_data}")

    输出:

    data: [0, 1, 2, 3, 4], mask: [1, 1, 1, 0, 1], new_data: [0, 1, 2, 4]
  5. 使用Python标准库中的itertools.filterfalse函数

    from itertools import filterfalse
    
    index_to_remove = 3
    data = [*range(5)]
    new_data = [*filterfalse(lambda i: i == index_to_remove, data)]
    
    print(f"data: {data}, new_data: {new_data}")

    输出:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]

I’m going to provide a functional (immutable) way of doing it.

  1. The standard and easy way of doing it is to use slicing:

    index_to_remove = 3
    data = [*range(5)]
    new_data = data[:index_to_remove] + data[index_to_remove + 1:]
    
    print(f"data: {data}, new_data: {new_data}")
    

    Output:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
    
  2. Use list comprehension:

    data = [*range(5)]
    new_data = [v for i, v in enumerate(data) if i != index_to_remove]
    
    print(f"data: {data}, new_data: {new_data}") 
    

    Output:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
    
  3. Use filter function:

    index_to_remove = 3
    data = [*range(5)]
    new_data = [*filter(lambda i: i != index_to_remove, data)]
    

    Output:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
    
  4. Using masking. Masking is provided by itertools.compress function in the standard library:

    from itertools import compress
    
    index_to_remove = 3
    data = [*range(5)]
    mask = [1] * len(data)
    mask[index_to_remove] = 0
    new_data = [*compress(data, mask)]
    
    print(f"data: {data}, mask: {mask}, new_data: {new_data}")
    

    Output:

    data: [0, 1, 2, 3, 4], mask: [1, 1, 1, 0, 1], new_data: [0, 1, 2, 4]
    
  5. Use itertools.filterfalse function from Python standard library

    from itertools import filterfalse
    
    index_to_remove = 3
    data = [*range(5)]
    new_data = [*filterfalse(lambda i: i == index_to_remove, data)]
    
    print(f"data: {data}, new_data: {new_data}")
    

    Output:

    data: [0, 1, 2, 3, 4], new_data: [0, 1, 2, 4]
    

回答 6

如果您事先不知道索引,这里的功能将起作用

def reverse_index(l, index):
    try:
        l.pop(index)
        return l
    except IndexError:
        return False

If you don’t know the index beforehand here is a function that will work

def reverse_index(l, index):
    try:
        l.pop(index)
        return l
    except IndexError:
        return False

回答 7

请注意,如果变量是列表列表,则某些方法将失败。例如:

v1 = [[range(3)] for x in range(4)]
v2 = v1[:3]+v1[4:] # this fails
v2

对于一般情况,使用

removed_index = 1
v1 = [[range(3)] for x in range(4)]
v2 = [x for i,x in enumerate(v1) if x!=removed_index]
v2

Note that if variable is list of lists, some approaches would fail. For example:

v1 = [[range(3)] for x in range(4)]
v2 = v1[:3]+v1[4:] # this fails
v2

For the general case, use

removed_index = 1
v1 = [[range(3)] for x in range(4)]
v2 = [x for i,x in enumerate(v1) if x!=removed_index]
v2

回答 8

如果要剪掉最后一个或第一个,请执行以下操作:

list = ["This", "is", "a", "list"]
listnolast = list[:-1]
listnofirst = list[1:]

如果将1更改为2,则将删除前2个字符,而不是第二个。希望这对您有所帮助!

If you want to cut out the last or the first do this:

list = ["This", "is", "a", "list"]
listnolast = list[:-1]
listnofirst = list[1:]

If you change 1 to 2 the first 2 characters will be removed not the second. Hope this still helps!


有趣好用的Python教程

退出移动版
微信支付
请使用 微信 扫码支付