使用Matplotlib绘制2D热图

问题:使用Matplotlib绘制2D热图

我想使用Matplotlib绘制2D热图。我的数据是一个n×n的Numpy数组,每个数组的值都在0到1之间。因此,对于该数组的(i,j)元素,我想在我的(i,j)坐标上绘制一个正方形热图,其颜色与数组中元素的值成比例。

我怎样才能做到这一点?

Using Matplotlib, I want to plot a 2D heat map. My data is an n-by-n Numpy array, each with a value between 0 and 1. So for the (i, j) element of this array, I want to plot a square at the (i, j) coordinate in my heat map, whose color is proportional to the element’s value in the array.

How can I do this?


回答 0

imshow()函数带有参数interpolation='nearest'cmap='hot'应该执行您想要的操作。

import matplotlib.pyplot as plt
import numpy as np

a = np.random.random((16, 16))
plt.imshow(a, cmap='hot', interpolation='nearest')
plt.show()

The imshow() function with parameters interpolation='nearest' and cmap='hot' should do what you want.

import matplotlib.pyplot as plt
import numpy as np

a = np.random.random((16, 16))
plt.imshow(a, cmap='hot', interpolation='nearest')
plt.show()


回答 1

Seaborn负责许多手动工作,并自动在图表的侧面绘制渐变等。

import numpy as np
import seaborn as sns
import matplotlib.pylab as plt

uniform_data = np.random.rand(10, 12)
ax = sns.heatmap(uniform_data, linewidth=0.5)
plt.show()

或者,您甚至可以绘制正方形矩阵的上/下左/右三角形,例如,一个正方形且对称的相关矩阵,因此绘制所有值无论如何都是多余的。

corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
    ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True,  cmap="YlGnBu")
    plt.show()

Seaborn takes care of a lot of the manual work and automatically plots a gradient at the side of the chart etc.

import numpy as np
import seaborn as sns
import matplotlib.pylab as plt

uniform_data = np.random.rand(10, 12)
ax = sns.heatmap(uniform_data, linewidth=0.5)
plt.show()

Or, you can even plot upper / lower left / right triangles of square matrices, for example a correlation matrix which is square and is symmetric, so plotting all values would be redundant anyway.

corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
    ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True,  cmap="YlGnBu")
    plt.show()


回答 2

对于二维numpy数组,简单地使用imshow()可能会帮助您:

import matplotlib.pyplot as plt
import numpy as np


def heatmap2d(arr: np.ndarray):
    plt.imshow(arr, cmap='viridis')
    plt.colorbar()
    plt.show()


test_array = np.arange(100 * 100).reshape(100, 100)
heatmap2d(test_array)

此代码产生连续的热图。

您可以colormap这里选择另一个内置的。

For a 2d numpy array, simply use imshow() may help you:

import matplotlib.pyplot as plt
import numpy as np


def heatmap2d(arr: np.ndarray):
    plt.imshow(arr, cmap='viridis')
    plt.colorbar()
    plt.show()


test_array = np.arange(100 * 100).reshape(100, 100)
heatmap2d(test_array)

This code produces a continuous heatmap.

You can choose another built-in colormap from here.


回答 3

我会使用matplotlib的pcolor / pcolormesh函数,因为它允许数据间距不均匀。

取自matplotlib的示例:

import matplotlib.pyplot as plt
import numpy as np

# generate 2 2d grids for the x & y bounds
y, x = np.meshgrid(np.linspace(-3, 3, 100), np.linspace(-3, 3, 100))

z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
# x and y are bounds, so z should be the value *inside* those bounds.
# Therefore, remove the last value from the z array.
z = z[:-1, :-1]
z_min, z_max = -np.abs(z).max(), np.abs(z).max()

fig, ax = plt.subplots()

c = ax.pcolormesh(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)
ax.set_title('pcolormesh')
# set the limits of the plot to the limits of the data
ax.axis([x.min(), x.max(), y.min(), y.max()])
fig.colorbar(c, ax=ax)

plt.show()

I would use matplotlib’s pcolor/pcolormesh function since it allows nonuniform spacing of the data.

Example taken from matplotlib:

import matplotlib.pyplot as plt
import numpy as np

# generate 2 2d grids for the x & y bounds
y, x = np.meshgrid(np.linspace(-3, 3, 100), np.linspace(-3, 3, 100))

z = (1 - x / 2. + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
# x and y are bounds, so z should be the value *inside* those bounds.
# Therefore, remove the last value from the z array.
z = z[:-1, :-1]
z_min, z_max = -np.abs(z).max(), np.abs(z).max()

fig, ax = plt.subplots()

c = ax.pcolormesh(x, y, z, cmap='RdBu', vmin=z_min, vmax=z_max)
ax.set_title('pcolormesh')
# set the limits of the plot to the limits of the data
ax.axis([x.min(), x.max(), y.min(), y.max()])
fig.colorbar(c, ax=ax)

plt.show()


回答 4

这是从csv执行操作的方法:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

# Load data from CSV
dat = np.genfromtxt('dat.xyz', delimiter=' ',skip_header=0)
X_dat = dat[:,0]
Y_dat = dat[:,1]
Z_dat = dat[:,2]

# Convert from pandas dataframes to numpy arrays
X, Y, Z, = np.array([]), np.array([]), np.array([])
for i in range(len(X_dat)):
        X = np.append(X, X_dat[i])
        Y = np.append(Y, Y_dat[i])
        Z = np.append(Z, Z_dat[i])

# create x-y points to be used in heatmap
xi = np.linspace(X.min(), X.max(), 1000)
yi = np.linspace(Y.min(), Y.max(), 1000)

# Z is a matrix of x-y values
zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic')

# I control the range of my colorbar by removing data 
# outside of my range of interest
zmin = 3
zmax = 12
zi[(zi<zmin) | (zi>zmax)] = None

# Create the contour plot
CS = plt.contourf(xi, yi, zi, 15, cmap=plt.cm.rainbow,
                  vmax=zmax, vmin=zmin)
plt.colorbar()  
plt.show()

dat.xyz形式在哪里

x1 y1 z1
x2 y2 z2
...

Here’s how to do it from a csv:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

# Load data from CSV
dat = np.genfromtxt('dat.xyz', delimiter=' ',skip_header=0)
X_dat = dat[:,0]
Y_dat = dat[:,1]
Z_dat = dat[:,2]

# Convert from pandas dataframes to numpy arrays
X, Y, Z, = np.array([]), np.array([]), np.array([])
for i in range(len(X_dat)):
        X = np.append(X, X_dat[i])
        Y = np.append(Y, Y_dat[i])
        Z = np.append(Z, Z_dat[i])

# create x-y points to be used in heatmap
xi = np.linspace(X.min(), X.max(), 1000)
yi = np.linspace(Y.min(), Y.max(), 1000)

# Z is a matrix of x-y values
zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic')

# I control the range of my colorbar by removing data 
# outside of my range of interest
zmin = 3
zmax = 12
zi[(zi<zmin) | (zi>zmax)] = None

# Create the contour plot
CS = plt.contourf(xi, yi, zi, 15, cmap=plt.cm.rainbow,
                  vmax=zmax, vmin=zmin)
plt.colorbar()  
plt.show()

where dat.xyz is in the form

x1 y1 z1
x2 y2 z2
...

matplotlib:如何在图像上绘制矩形

问题:matplotlib:如何在图像上绘制矩形

如何在图像上绘制矩形,如下所示:

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
im = np.array(Image.open('dog.png'), dtype=np.uint8)
plt.imshow(im)

我不知道该如何进行。

How to draw a rectangle on an image, like this:

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
im = np.array(Image.open('dog.png'), dtype=np.uint8)
plt.imshow(im)

I don’t know how to proceed.


回答 0

您可以将Rectangle补丁添加到matplotlib轴。

例如(在此处使用教程中的图像):

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np

im = np.array(Image.open('stinkbug.png'), dtype=np.uint8)

# Create figure and axes
fig,ax = plt.subplots(1)

# Display the image
ax.imshow(im)

# Create a Rectangle patch
rect = patches.Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

plt.show()

You can add a Rectangle patch to the matplotlib Axes.

For example (using the image from the tutorial here):

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np

im = np.array(Image.open('stinkbug.png'), dtype=np.uint8)

# Create figure and axes
fig,ax = plt.subplots(1)

# Display the image
ax.imshow(im)

# Create a Rectangle patch
rect = patches.Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

plt.show()


回答 1

您需要使用补丁。

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig2 = plt.figure()
ax2 = fig2.add_subplot(111, aspect='equal')

ax2.add_patch(
     patches.Rectangle(
        (0.1, 0.1),
        0.5,
        0.5,
        fill=False      # remove background
     ) ) 
fig2.savefig('rect2.png', dpi=90, bbox_inches='tight')

You need use patches.

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig2 = plt.figure()
ax2 = fig2.add_subplot(111, aspect='equal')

ax2.add_patch(
     patches.Rectangle(
        (0.1, 0.1),
        0.5,
        0.5,
        fill=False      # remove background
     ) ) 
fig2.savefig('rect2.png', dpi=90, bbox_inches='tight')

回答 2

不需要子图,并且pyplot可以显示PIL图像,因此可以进一步简化:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Image

im = Image.open('stinkbug.png')

# Display the image
plt.imshow(im)

# Get the current reference
ax = plt.gca()

# Create a Rectangle patch
rect = Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

或者,简短版本:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Image

# Display the image
plt.imshow(Image.open('stinkbug.png'))

# Add the patch to the Axes
plt.gca().add_patch(Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none'))

There is no need for subplots, and pyplot can display PIL images, so this can be simplified further:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Image

im = Image.open('stinkbug.png')

# Display the image
plt.imshow(im)

# Get the current reference
ax = plt.gca()

# Create a Rectangle patch
rect = Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

Or, the short version:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Image

# Display the image
plt.imshow(Image.open('stinkbug.png'))

# Add the patch to the Axes
plt.gca().add_patch(Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none'))

回答 3

据我了解,matplotlib是一个绘图库。

如果要更改图像数据(例如,在图像上绘制矩形),则可以使用PIL的ImageDrawOpenCV或类似的东西。

这是PIL的ImageDraw方法来绘制矩形

这是OpenCV绘制矩形的方法之一

您的问题询问了有关Matplotlib的问题,但可能应该只是询问有关在图像上绘制矩形的问题。

这是另一个解决我想知道的问题的问题: 使用PIL在其中绘制一个矩形和一个文本

From my understanding matplotlib is a plotting library.

If you want to change the image data (e.g. draw a rectangle on an image), you could use PIL’s ImageDraw, OpenCV, or something similar.

Here is PIL’s ImageDraw method to draw a rectangle.

Here is one of OpenCV’s methods for drawing a rectangle.

Your question asked about Matplotlib, but probably should have just asked about drawing a rectangle on an image.

Here is another question which addresses what I think you wanted to know: Draw a rectangle and a text in it using PIL


在Windows 7上添加Python路径

问题:在Windows 7上添加Python路径

我一直在尝试在Windows 7上将Python路径添加到命令行中,但是无论我尝试哪种方法,似乎都没有任何效果。我使用了该set命令,尝试通过“编辑环境”变量提示符等添加它。

此外,如果我在命令行上运行set命令,它将列出此内容

python = c:\python27

但是它仍然无法识别Python命令。

阅读文档以及其他各种资源似乎无济于事。

编辑:为了进一步说明,我在编辑环境提示中将Python可执行文件的路径附加到PATH。似乎不起作用。

I’ve been trying to add the Python path to the command line on Windows 7, yet no matter the method I try, nothing seems to work. I’ve used the set command, I’ve tried adding it through the Edit Environment variables prompt etc.

Further more if I run the set command on the command line it lists this

python = c:\python27

Yet it still doesn’t recognize the Python command.

Reading the documentation, and various other sources hasn’t seemed to help.

Edit: Just to clarify further, I’ve appended the path of the Python executable to PATH in edit environment prompt. Doesn’t seem to work.


回答 0

  1. 按住Win并按Pause
  2. 单击高级系统设置。
  3. 单击环境变量。
  4. 追加;C:\python27Path变量。
  5. 重新启动命令提示符。
  1. Hold Win and press Pause.
  2. Click Advanced System Settings.
  3. Click Environment Variables.
  4. Append ;C:\python27 to the Path variable.
  5. Restart Command Prompt.

回答 1

在Windows中设置环境变量时,我在很多情况下都出错了。我认为我应该在这里分享我过去的一些错误,希望对别人有所帮助。(这些适用于所有环境变量,不仅适用于设置Python路径)

当心这些可能的错误:

  1. 杀死并重新打开您的Shell窗口:对环境变量进行更改后,您必须重新启动要对其进行测试的窗口。
  2. 设置变量时没有空间。请确保您添加;C:\Python27无任何空格。(通常C:\SomeOther; C:\Python27在分号后尝试使用空格(␣)是不正确的。)
  3. 阐明完整路径时,请使用向后斜线。尝试时会看到正斜杠,echo $PATH但只有反斜杠对我有用。
  4. 不要添加最后的反斜杠。只有C:\Python27C:\Python27\

希望这对某人有帮助。

When setting Environmental Variables in Windows, I have gone wrong on many, many occasions. I thought I should share a few of my past mistakes here hoping that it might help someone. (These apply to all Environmental Variables, not just when setting Python Path)

Watch out for these possible mistakes:

  1. Kill and reopen your shell window: Once you make a change to the ENVIRONMENTAL Variables, you have to restart the window you are testing it on.
  2. NO SPACES when setting the Variables. Make sure that you are adding the ;C:\Python27 WITHOUT any spaces. (It is common to try C:\SomeOther; C:\Python27 That space (␣) after the semicolon is not okay.)
  3. USE A BACKWARD SLASH when spelling out your full path. You will see forward slashes when you try echo $PATH but only backward slashes have worked for me.
  4. DO NOT ADD a final backslash. Only C:\Python27 NOT C:\Python27\

Hope this helps someone.


回答 2

以管理员权限打开cmd .exe(右键单击应用程序)。然后输入:

setx路径“%path%; C:\ Python27;”

请记住以分号结尾,并且不要包含斜杠。

Open cmd.exe with administrator privileges (right click on app). Then type:

setx path “%path%;C:\Python27;”

Remember to end with a semi-colon and don’t include a trailing slash.


回答 3

我已经很久没有这个问题了。我以各种方式将其添加到我的路径中,但这终于对我有用:

  1. 右键单击“我的电脑”
  2. 点击“属性”
  3. 点击侧面板中的“高级系统设置”
  4. 点击“环境变量”
  5. 点击系统变量下面的“新建”
  6. 输入名称pythonexe(或您想要的任何名称
  7. 在值输入路径你的Python(例如:C:\Python32\
  8. 现在,编辑Path变量(在系统部分),然后添加%pythonexe%;到已经存在的末尾

IDK为什么这样做有效,但对我有用。

然后尝试在命令行中输入“ python”,它应该可以工作!


编辑:

最近,我一直在使用该程序,它似乎运行良好。还有一个看起来也不错,尽管我从未尝试过。

I’ve had a problem with this for a LONG time. I added it to my path in every way I could think of but here’s what finally worked for me:

  1. Right click on “My computer”
  2. Click “Properties”
  3. Click “Advanced system settings” in the side panel
  4. Click “Environment Variables”
  5. Click the “New” below system variables
  6. in name enter pythonexe (or anything you want)
  7. in value enter the path to your python (example: C:\Python32\)
  8. Now edit the Path variable (in the system part) and add %pythonexe%; to the end of what’s already there

IDK why this works but it did for me.

then try typing “python” into your command line and it should work!


Edit:

Lately I’ve been using this program which seems to work pretty well. There’s also this one which looks pretty good too, although I’ve never tried it.


回答 4

尝试将此python.bat文件添加到System32文件夹,然后在键入时命令行将运行pythonpython

python.bat

@C:\Python27\python.exe %*

资源:

https://github.com/KartikTalwar/dotfiles/blob/master/bat/python.bat

Try adding this python.bat file to System32 folder and the command line will now run python when you type in python

python.bat

@C:\Python27\python.exe %*

Source:

https://github.com/KartikTalwar/dotfiles/blob/master/bat/python.bat


回答 5

您可以使用命令从当前cmd窗口设置路径PATH =。那只会为当前的cmd实例添加它。如果要永久添加,则应将其添加到系统变量。(计算机>高级系统设置>环境变量)

您将转到您的cmd实例,然后放入PATH=C:/Python27/;%PATH%

You can set the path from the current cmd window using the PATH = command. That will only add it for the current cmd instance. if you want to add it permanently, you should add it to system variables. (Computer > Advanced System Settings > Environment Variables)

You would goto your cmd instance, and put in PATH=C:/Python27/;%PATH%.


回答 6

确保您没有在新目录之前添加空格。

好:旧;旧;旧;新

不好:老;老;老;新

Make sure you don’t add a space before the new directory.

Good: old;old;old;new

Bad: old;old;old; new


回答 7

Python带有一个小型工具,可以执行此操作。从命令行运行:

c:\python27\tools\scripts\win_add2path.py

确保关闭命令窗口(使用exit或关闭按钮),然后再次打开它。

Python comes with a small utility that does just this. From the command line run:

c:\python27\tools\scripts\win_add2path.py

Make sure you close the command window (with exit or the close button) and open it again.


回答 8

以下程序将python可执行路径和subdir脚本(例如pip和easy_install的安装位置)添加到您的环境中。它从绑定.py扩展名的注册表项中找到python可执行文件的路径。它将删除您环境中的旧python路径。也适用于XP(可能还有Vista)。它仅使用基本Windows安装程序随附的模块。

# coding: utf-8

import sys
import os
import time
import _winreg
import ctypes

def find_python():
    """
    retrieves the commandline for .py extensions from the registry
    """
    hKey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
                           r'Python.File\shell\open\command')
    # get the default value
    value, typ = _winreg.QueryValueEx (hKey, None)
    program = value.split('"')[1]
    if not program.lower().endswith(r'\python.exe'):
        return None
    return os.path.dirname(program)

def extend_path(pypath, remove=False, verbose=0, remove_old=True,
                script=False):
    """
    extend(pypath) adds pypath to the PATH env. variable as defined in the
    registry, and then notifies applications (e.g. the desktop) of this change.
    !!! Already opened DOS-Command prompts are not updated. !!!
    Newly opened prompts will have the new path (inherited from the 
    updated windows explorer desktop)
    options:
    remove (default unset), remove from PATH instead of extend PATH
    remove_old (default set), removes any (old) python paths first
    script (default unset), try to add/remove the Scripts subdirectory 
        of pypath (pip, easy_install) as well
    """
    _sd = 'Scripts' # scripts subdir
    hKey = _winreg.OpenKey (_winreg.HKEY_LOCAL_MACHINE,
               r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
               0, _winreg.KEY_READ | _winreg.KEY_SET_VALUE)

    value, typ = _winreg.QueryValueEx (hKey, "PATH")
    vals = value.split(';')
    assert isinstance(vals, list)
    if not remove and remove_old:
        new_vals = []
        for v in vals:
            pyexe = os.path.join(v, 'python.exe')
            if v != pypath and os.path.exists(pyexe):
                if verbose > 0:
                    print 'removing from PATH:', v
                continue
            if script and v != os.path.join(pypath, _sd) and \
               os.path.exists(v.replace(_sd, pyexe)):
                if verbose > 0:
                    print 'removing from PATH:', v
                continue
            new_vals.append(v)
        vals = new_vals
    if remove:
        try:
            vals.remove(pypath)
        except ValueError:
            if verbose > 0:
                print 'path element', pypath, 'not found'
            return
        if script:
            try:
                vals.remove(os.path.join(pypath, _sd))
            except ValueError:
                pass
            print 'removing from PATH:', pypath
    else:
        if pypath in vals:
            if verbose > 0:
                print 'path element', pypath, 'already in PATH'
            return
        vals.append(pypath)
        if verbose > 1:
            print 'adding to PATH:', pypath
        if script:
            if not pypath + '\\Scripts' in vals:
                vals.append(pypath + '\\Scripts')
            if verbose > 1:
                print 'adding to PATH:', pypath + '\\Scripts'
    _winreg.SetValueEx(hKey, "PATH", 0, typ, ';'.join(vals) )
    _winreg.SetValueEx(hKey, "OLDPATH", 0, typ, value )
    _winreg.FlushKey(hKey)
    # notify other programs
    SendMessage = ctypes.windll.user32.SendMessageW
    HWND_BROADCAST = 0xFFFF
    WM_SETTINGCHANGE = 0x1A
    SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, u'Environment')
    if verbose > 1:
        print 'Do not forget to restart any command prompts'

if __name__ == '__main__':
    remove = '--remove' in sys.argv
    script = '--noscripts' not in sys.argv
    extend_path(find_python(), verbose=2, remove=remove, script=script)

The following program will add the python executable path and the subdir Scripts (which is where e.g. pip and easy_install are installed) to your environment. It finds the path to the python executable from the registry key binding the .py extension. It will remove old python paths in your environment. Works with XP (and probably Vista) as well. It only uses modules that come with the basic windows installer.

# coding: utf-8

import sys
import os
import time
import _winreg
import ctypes

def find_python():
    """
    retrieves the commandline for .py extensions from the registry
    """
    hKey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
                           r'Python.File\shell\open\command')
    # get the default value
    value, typ = _winreg.QueryValueEx (hKey, None)
    program = value.split('"')[1]
    if not program.lower().endswith(r'\python.exe'):
        return None
    return os.path.dirname(program)

def extend_path(pypath, remove=False, verbose=0, remove_old=True,
                script=False):
    """
    extend(pypath) adds pypath to the PATH env. variable as defined in the
    registry, and then notifies applications (e.g. the desktop) of this change.
    !!! Already opened DOS-Command prompts are not updated. !!!
    Newly opened prompts will have the new path (inherited from the 
    updated windows explorer desktop)
    options:
    remove (default unset), remove from PATH instead of extend PATH
    remove_old (default set), removes any (old) python paths first
    script (default unset), try to add/remove the Scripts subdirectory 
        of pypath (pip, easy_install) as well
    """
    _sd = 'Scripts' # scripts subdir
    hKey = _winreg.OpenKey (_winreg.HKEY_LOCAL_MACHINE,
               r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
               0, _winreg.KEY_READ | _winreg.KEY_SET_VALUE)

    value, typ = _winreg.QueryValueEx (hKey, "PATH")
    vals = value.split(';')
    assert isinstance(vals, list)
    if not remove and remove_old:
        new_vals = []
        for v in vals:
            pyexe = os.path.join(v, 'python.exe')
            if v != pypath and os.path.exists(pyexe):
                if verbose > 0:
                    print 'removing from PATH:', v
                continue
            if script and v != os.path.join(pypath, _sd) and \
               os.path.exists(v.replace(_sd, pyexe)):
                if verbose > 0:
                    print 'removing from PATH:', v
                continue
            new_vals.append(v)
        vals = new_vals
    if remove:
        try:
            vals.remove(pypath)
        except ValueError:
            if verbose > 0:
                print 'path element', pypath, 'not found'
            return
        if script:
            try:
                vals.remove(os.path.join(pypath, _sd))
            except ValueError:
                pass
            print 'removing from PATH:', pypath
    else:
        if pypath in vals:
            if verbose > 0:
                print 'path element', pypath, 'already in PATH'
            return
        vals.append(pypath)
        if verbose > 1:
            print 'adding to PATH:', pypath
        if script:
            if not pypath + '\\Scripts' in vals:
                vals.append(pypath + '\\Scripts')
            if verbose > 1:
                print 'adding to PATH:', pypath + '\\Scripts'
    _winreg.SetValueEx(hKey, "PATH", 0, typ, ';'.join(vals) )
    _winreg.SetValueEx(hKey, "OLDPATH", 0, typ, value )
    _winreg.FlushKey(hKey)
    # notify other programs
    SendMessage = ctypes.windll.user32.SendMessageW
    HWND_BROADCAST = 0xFFFF
    WM_SETTINGCHANGE = 0x1A
    SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, u'Environment')
    if verbose > 1:
        print 'Do not forget to restart any command prompts'

if __name__ == '__main__':
    remove = '--remove' in sys.argv
    script = '--noscripts' not in sys.argv
    extend_path(find_python(), verbose=2, remove=remove, script=script)

回答 9

我知道这篇文章很旧,但我想补充一点,该解决方案假设使用admin privs。如果您没有这些,可以:

转到控制面板,键入路径(此为Windows 7,现在在搜索框中),然后单击“为您的帐户编辑环境变量”。现在,您将看到环境变量对话框,其顶部为“用户变量”,而其下方为“系统变量”。

您可以作为用户单击顶部的“新建”按钮并添加:

变量名称:PATH
变量值:C:\ Python27

(任何地方都没有空格),然后单击“确定”。重新启动命令提示符后,User变量中的所有PATH都将附加到系统路径的末尾。它不会以任何其他方式替换PATH。

如果要设置特定的完整路径,最好创建一个像这样的批处理文件:

@echo off
PATH C:\User\Me\Programs\mingw\bin;C:\User\Me\Programs;C:\Windows\system32
title Compiler Environment - %Username%@%Computername%
cmd

将其命名为“ compiler.bat”或双击以启动它。或链接到它。或固定等等…

I know this post is old but I’d like to add that the solutions assume admin privs. If you don’t have those you can:

Go to control panel, type path (this is Windows 7 now so that’s in the Search box) and click “Edit Environment variables for your account”. You’ll now see the Environment Variable dialog with “User variables” on the top and “System variables” below.

You can, as a user, click the top “New” button and add:

Variable name: PATH
Variable value: C:\Python27

(no spaces anywhere) and click OK. Once your command prompt is restarted, any PATH in the User variables is appended to the end of the System Path. It doesn’t replace the PATH in any other way.

If you want a specific full path set up, you’re better off creating a batch file like this little one:

@echo off
PATH C:\User\Me\Programs\mingw\bin;C:\User\Me\Programs;C:\Windows\system32
title Compiler Environment - %Username%@%Computername%
cmd

Call it “compiler.bat” or whatever and double click to start it. Or link to it. Or pin it etc…


回答 10

您需要在系统变量中进行更改
-右键单击“我的电脑”
-单击“属性”
-单击侧面板中的“高级系统设置”
-单击环境变量-您将分为两部分变量和系统变量
-在系统变量部分下搜索变量’Path’单击编辑并添加
"C:\Python27;"(不带引号)将其保存
-现在打开命令行类型’path’ 并按Enter,您将看到路径变量已被修改
-现在输入python --version您将看到python版本

完成了

You need to make changes in your system variable
— Right click on “My computer”
— Click “Properties”
— Click “Advanced system settings” in the side panel
— Click on Environment Variable — You will two sections of user variable and system variable
— Under system variable section search for the variable ‘Path’ click on edit and add
"C:\Python27;" (without quotes) save it
— Now open command line type ‘path’ hit enter you will see path variable has been modified
— Now type python --version you will see the python version

And it is done


回答 11

对于尝试使用Python 3.3+实现此目标的任何人,Windows安装程序现在都提供了一个将python.exe添加到系统搜索路径的选项。在docs中阅读更多内容。

For anyone trying to achieve this with Python 3.3+, the Windows installer now includes an option to add python.exe to the system search path. Read more in the docs.


回答 12

使用Windows环境变量始终是一种可怕的经历。最近,我发现了一个令人称奇的工具,称为Rapid Environment Editor,它提供了非常简单的GUI来管理它们。

如果您使用Chocolatey,则可以使用安装它choco install rapidee。否则,请访问http://www.rapidee.com/cn/download

重新阅读此内容,听起来像是有偿的,但是我发誓我不是!一段时间以来,它一直是我工具箱中最有用的实用程序之一,但令我惊讶的是似乎没人知道它。

Working with Windows environment variables is always a horrible experience. Recently, I found an amazing tool called Rapid Environment Editor, which gives an awesomely simple GUI for managing them.

If you use chocolatey, you can install it using choco install rapidee. Otherwise, take a look at http://www.rapidee.com/en/download

Re-reading this, it sounds like a paid shill, but I swear I’m not! It’s just been one of the most useful utilities in my toolkit for a while and I’m surprised no one seems to know about it.


回答 13

如果Python与其他程序一起安装,例如我的ArcGIS 10.1,则还必须在环境变量中包含指向python.exe路径的所有其他文件夹。

所以我的环境变量看起来像这样:

系统变量>路径>添加 ;C:\Python27\ArcGIS10.1

If Python was installed with another program, such as ArcGIS 10.1 in my case, then you also must include any extra folders that path to the python.exe in your Environment Variables.

So my Environment Variables looks like this:

System variables > Path > add ;C:\Python27\ArcGIS10.1


回答 14

这个问题已经很老了,但是我遇到了一个类似的问题,这里没有列出我的特定解决方案:

确保您的PATH中没有不存在的文件夹。

就我而言,我有一堆默认文件夹(Windows,Powershell,Sql Server等),然后是C:\bin我通常使用的自定义,然后进行了其他各种调整,例如c:\python17等等。事实证明,cmd处理器发现c:\bin没有不存在,然后停止处理其余变量。

另外,我不知道如果没有PATH manager,我是否会注意到这一点。它很好地强调了该项目无效的事实。

This question is pretty old, but I just ran into a similar problem and my particular solution wasn’t listed here:

Make sure you don’t have a folder in your PATH that doesn’t exist.

In my case, I had a bunch of default folders (Windows, Powershell, Sql Server, etc) and then a custom C:\bin that I typically use, and then various other tweaks like c:\python17, etc. It turns out that the cmd processor was finding that c:\bin didn’t exist and then stopped processing the rest of the variable.

Also, I don’t know that I ever would have noticed this without PATH manager. It nicely highlighted the fact that that item was invalid.


回答 15

我刚刚使用选项“将python添加到PATH”在Windows 7上安装了Python 3.3。

在PATH变量中,安装程序会自动添加最后一个反斜杠C:\Python33\ ,因此在命令提示符下不起作用(我尝试多次关闭/打开提示符)

我删除了最后的反斜杠,然后它起作用了:C:\Python33

感谢Ram Narasimhan给您的提示4!

I just installed Python 3.3 on Windows 7 using the option “add python to PATH”.

In PATH variable, the installer automatically added a final backslash: C:\Python33\ and so it did not work on command prompt (i tried closing/opening the prompt several times)

I removed the final backslash and then it worked: C:\Python33

Thanks Ram Narasimhan for your tip #4 !


回答 16

我使用cmd在Win7 64位下组织了这样的python环境变量。

PYTHONPATH通过Windows的环境变量菜单设置变量,并将其添加%PYTHONPATH%PATH变量中:

...;%PYTHONPATH%

cmd shell将变量正确扩展为:

C:\>echo %PYTHONPATH%
C:\python27;c:\python27\lib;C:\python27\scripts

不要忘记在更改PATH之后重新启动cmd shell。

I organized my python environment variable like this under Win7 64-bit using cmd.

I set the variable PYTHONPATH via environment variable menue of windows and added %PYTHONPATH% to the PATH variable:

...;%PYTHONPATH%

The cmd shell expands the variable correctly to this:

C:\>echo %PYTHONPATH%
C:\python27;c:\python27\lib;C:\python27\scripts

Do not forget to restart cmd shell after changing PATH.


回答 17

将其写在命令提示符上:

set Path=%path%

用Python文件夹示例的路径替换%path%:

set Path=C:/Python27

write that on your Command Prompt:

set Path=%path%

Replace %path% by the Path of your Python Folder Example:

set Path=C:/Python27

回答 18

如果您对设置python的路径感到沮丧,只需下载新版本的python并卸载旧版本的python,并在安装新版本时询问是否设置路径标记并安装

这是最好的方法

If you have got frustrated by setting the path for the python just download the new version of python uninstall the older version of the python and while installing the new version it will ask whether to set path mark that and install

its the best way


如何修复PyDev“导入时未定义变量”错误?

问题:如何修复PyDev“导入时未定义变量”错误?

我有一个在Eclipse中使用PyDev的Python项目,并且PyDev不断为我的代码生成错误错误。我有一个settings定义settings对象的模块。我将其导入模块b并使用以下属性分配属性:

from settings import settings
settings.main = object()

在我的一些代码(但不是全部)中,语句如下:

from settings import settings
print settings.main 

…即使在代码运行没有问题的情况下,也会在Eclipse代码错误窗格中生成“从import:main导入未定义的变量”消息。我该如何纠正?

I’ve got a Python project using PyDev in Eclipse, and PyDev keeps generating false errors for my code. I have a module settings that defines a settings object. I import that in module b and assign an attribute with:

from settings import settings
settings.main = object()

In some of my code–but not all of it, statements like:

from settings import settings
print settings.main 

… generate “Undefined variable from import: main” messages in the Eclipse code error pane, even though the code runs without a problem. How can I correct these?


回答 0

对于您项目中的代码,唯一的方法是添加一个声明,声明您希望-可能受到a的保护,if False从而使其无法执行(如果您执行了静态代码分析,则只能看到您看到的内容,而不能看到运行时信息)自己打开该模块,则不会显示预期为main。

为了克服这个问题,有一些选择:

  1. 如果它是某个外部模块,则可以将其添加到,forced builtins以便PyDev为其生成外壳以获取运行时信息(有关详细信息,请参见http://pydev.org/manual_101_interpreter.html),即:大多数情况下,PyDev会将模块导入外壳中,并对模块中找到的类进行dir(module)dir,以显示完成内容并进行代码分析。

  2. 您可以在出现错误的行中使用Ctrl + 1(对于Mac为Cmd + 1),PyDev将为您提供一个添加注释的选项,以忽略该错误。

  3. 可以创建一个stub模块并将其添加到补全中predefinedhttp://pydev.org/manual_101_interpreter.html上也有详细信息)。

For code in your project, the only way is adding a declaration saying that you expected that — possibly protected by an if False so that it doesn’t execute (the static code-analysis only sees what you see, not runtime info — if you opened that module yourself, you’d have no indication that main was expected).

To overcome this there are some choices:

  1. If it is some external module, it’s possible to add it to the forced builtins so that PyDev spawns a shell for it to obtain runtime information (see http://pydev.org/manual_101_interpreter.html for details) — i.e.: mostly, PyDev will import the module in a shell and do a dir(module) and dir on the classes found in the module to present completions and make code analysis.

  2. You can use Ctrl+1 (Cmd+1 for Mac) in a line with an error and PyDev will present you an option to add a comment to ignore that error.

  3. It’s possible to create a stub module and add it to the predefined completions (http://pydev.org/manual_101_interpreter.html also has details on that).


回答 1

我正在使用opencv,它依赖于二进制文件等,所以我有脚本,其中每隔一行都有这个愚蠢的错误。Python是一种动态语言,因此不应将这种情况视为错误。

我通过以下步骤彻底删除了这些错误:

窗口->首选项-> PyDev->编辑器->代码分析->未定义->来自导入的未定义变量->忽略

就是这样。

也可能是,窗口->首选项-> PyDev->编辑器->代码分析->导入->找不到导入->忽略

I’m using opencv which relies on binaries etc so I have scripts where every other line has this silly error. Python is a dynamic language so such occasions shouldn’t be considered errors.

I removed these errors altogether by going to:

Window -> Preferences -> PyDev -> Editor -> Code Analysis -> Undefined -> Undefined Variable From Import -> Ignore

And that’s that.

It may also be, Window -> Preferences -> PyDev -> Editor -> Code Analysis -> Imports -> Import not found -> Ignore


回答 2

标为答案的帖子提供了一种解决方法,而不是解决方案。

此解决方案适用于我:

  • Window - Preferences - PyDev - Interpreters - Python Interpreter
  • 转到Forced builtins标签
  • 点击 New...
  • 输入模块名称(multiprocessing以我为例),然后单击OK

错误消息不仅将消失,而且模块成员也将被识别。

The post marked as answer gives a workaround, not a solution.

This solution works for me:

  • Go to Window - Preferences - PyDev - Interpreters - Python Interpreter
  • Go to the Forced builtins tab
  • Click on New...
  • Type the name of the module (multiprocessing in my case) and click OK

Not only will the error messages disappear, the module members will also be recognized.


回答 3

我在Eclipse / PyDev项目中遇到类似的问题。在这个项目中,python代码的根目录是项目的子目录。

--> MyProject
 + --> src         Root of python code
   + --> module1     A module 
   + --> module2     Another module
 + --> docs
 + --> test

在调试或运行项目时,一切都很好,因为工作目录已设置到正确的位置。但是,PyDev代码分析未能找到来自module1或module2的任何导入。

解决方案是编辑项目属性-> PyDev-PYTHONPATH部分,然后从“源文件夹”选项卡中删除/ MyProject,然后向其中添加/ MyProject / src。

I was having a similar problem with an Eclipse/PyDev project. In this project the root directory of the python code was a sub-directory of the project.

--> MyProject
 + --> src         Root of python code
   + --> module1     A module 
   + --> module2     Another module
 + --> docs
 + --> test

When the project was debugged or run everything was fine as the working directory was set to the correct place. However the PyDev code analysis was failing to find any imports from module1 or module2.

Solution was to edit the project properties -> PyDev – PYTHONPATH section and remove /MyProject from the source folders tab and add /MyProject/src to it instead.


回答 4

这对我有用:

步骤1)移除解释器,再次自动配置

步骤2)窗口-首选项-PyDev-解释器-Python解释器转到“强制内置”选项卡。单击“新建…”。输入模块名称(在我的情况下为curses),然后单击“确定”。

步骤3)右键单击项目浏览器中出现错误的模块。转到PyDev->代码分析。

This worked for me:

step 1) Removing the interpreter, auto configuring it again

step 2) Window – Preferences – PyDev – Interpreters – Python Interpreter Go to the Forced builtins tab Click on New… Type the name of the module (curses in my case) and click OK

step 3) Right click in the project explorer on whichever module is giving errors. Go to PyDev->Code analysis.


回答 5

我有同样的问题。我在Windows上使用Python和Eclipse。该代码运行得很好,但是Eclipse到处都会显示错误。将文件夹“ Lib”的名称更改为“ lib”(C:\ Python27 \ lib)之后,问题得以解决。看来,如果字母的大写字母与配置文件中的字母不匹配,这有时会引起问题(但似乎并不总是这样,因为错误检查很长一段时间就可以在问题突然出现之前很明显了原因)。

I had the same problem. I am using Python and Eclipse on Windows. The code was running just fine, but eclipse show errors everywhere. After I changed the name of the folder ‘Lib’ to ‘lib’ (C:\Python27\lib), the problem was solved. It seems that if the capitalization of the letters doesn’t match the one in the configuration file, this will sometimes cause problems (but it seems like not always, because the error checking was fine for long time before the problems suddenly appeared for no obvious reason).


回答 6

我正在做什么的一个近似值:

import module.submodule

class MyClass:
    constant = submodule.constant

皮林特说: E: 4,15: Undefined variable 'submodule' (undefined-variable)

我通过更改导入来解决此问题,例如:

from module.submodule import CONSTANT

class MyClass:
    constant = CONSTANT

注意:我还使用导入的变量重命名了名称,以反映其常量性质。

An approximation of what I was doing:

import module.submodule

class MyClass:
    constant = submodule.constant

To which pylint said: E: 4,15: Undefined variable 'submodule' (undefined-variable)

I resolved this by changing my import like:

from module.submodule import CONSTANT

class MyClass:
    constant = CONSTANT

Note: I also renamed by imported variable to have an uppercase name to reflect its constant nature.


回答 7

您可能只需要在Eclipse中重新配置python路径。见我的回答对一个类似问题。

It is possible you just need to re-configure your python path within Eclipse. See my answer to a similar question.


回答 8

在首选项-> PyDev-> PyLint 传递给PyLint的参数下添加以下行:

--generated-members=objects

您将需要针对每个生成的进行此操作。我通过谷歌搜索找到了这个,但是我丢失了参考。

in preferences –> PyDev –> PyLint under arguments to pass to PyLint add this line:

--generated-members=objects

you will need to do this for each generated . I found this by googling, but I lost the reference.


回答 9

在项目浏览器中右键单击出现错误的模块。转到PyDev->删除错误标记。

Right click in the project explorer on whichever module is giving errors. Go to PyDev->Remove Error Markers.


回答 10

我的回答没有任何新贡献,只是我遇到的一个具体例子。

import gtk.gdk

w = gtk.gdk.get_default_root_window()

PyDev显示错误消息“来自导入的未定义变量:get_default_root_window()”

在python shell中,您可以看到这是一个“内置”模块,如上面的答案所述:

>>> import gtk.gdk
>>> gtk.gdk
<module 'gtk.gdk' (built-in)>

现在,在Window-> Preferences-> PyDev-> Interpreters-> Python Interpreter下,选择选项卡“ Forced Builtins”并将“ gtk.gdk”添加到列表中。

现在错误消息不再显示。

My answer doesn’t contribute anything new, just a concrete example I encountered.

import gtk.gdk

w = gtk.gdk.get_default_root_window()

PyDev showed the error message “Undefined variable from import: get_default_root_window()”

In the python shell you can see that this is a ‘built-in’ module as mentioned in a answer above:

>>> import gtk.gdk
>>> gtk.gdk
<module 'gtk.gdk' (built-in)>

Now under Window->Preferences->PyDev->Interpreters->Python Interpreter, I selected the tab ‘Forced Builtins’ and added ‘gtk.gdk’ to the list.

Now the error message didn’t show anymore.


回答 11

我发现这两个步骤一直对我有用:

  1. 确认(否则添加)模块的父文件夹到PYTHONPATH。
  2. 将模块的全名添加到强制内置。

这里要注意的事情:

  • 一些流行的模块会安装一些具有相同名称的父对子对。在这些情况下,除了已确认/添加的其他父项文件夹之外,还必须将该父项添加到PYTHONPATH中。

  • 当添加到强制内置时,请使用(例如)“ google.appengine.api.memcache”,而不是仅使用“ memcache”,在此示例中,“ google”是PYTHONPATH中定义的文件夹的直接子代。

I find that these 2 steps work for me all the time:

  1. Confirm (else add) the parent folder of the module to the PYTHONPATH.
  2. Add FULL name of the module to forced builtins.

The things to note here:

  • Some popular modules install with some parent and child pair having the same name. In these cases you also have to add that parent to PYTHONPATH, in addition to its grandparent folder, which you already confirmed/added for everything else.

  • Use (for example) “google.appengine.api.memcache” when adding to forced builtins, NOT “memcache” only, where “google” in this example, is an immediate child of a folder defined in PYTHONPATH.


回答 12

如果确定脚本已运行并且是错误警报,请转至“首选项”>“ PyDev”>“编辑器”>“代码分析”。将错误降级为警告。

http://www.pydev.org/manual_adv_code_analysis.html

If you’re sure that your script runs and that it is a false alarm, Go to Preferences > PyDev > Editor > Code Analysis. Demote the errors to warnings.

http://www.pydev.org/manual_adv_code_analysis.html


Python-何时使用文件vs打开

问题:Python-何时使用文件vs打开

fileopenPython 和有什么不一样?我什么时候应该使用哪个?(假设我处于2.5级)

What’s the difference between file and open in Python? When should I use which one? (Say I’m in 2.5)


回答 0

您应该始终使用open()

文档所述:

打开文件时,最好使用open()而不是直接调用此构造函数。文件更适合类型测试(例如,编写“ isinstance(f,file)”)。

另外,自Python 3.0起file() 已被删除

You should always use open().

As the documentation states:

When opening a file, it’s preferable to use open() instead of invoking this constructor directly. file is more suited to type testing (for example, writing “isinstance(f, file)”).

Also, file() has been removed since Python 3.0.


回答 1

原因有两个:python哲学“应该有一种实现方法”并且file正在消失。

file是实际类型(使用例如file('myfile.txt')调用其构造函数)。open是工厂函数,它将返回文件对象。

在python 3.0 file中,它将从内置变为由io库中的多个类实现(有点类似于带有缓冲读取器的Java等)。

Two reasons: The python philosophy of “There ought to be one way to do it” and file is going away.

file is the actual type (using e.g. file('myfile.txt') is calling its constructor). open is a factory function that will return a file object.

In python 3.0 file is going to move from being a built-in to being implemented by multiple classes in the io library (somewhat similar to Java with buffered readers, etc.)


回答 2

file()是一种类型,例如int或列表。open()是用于打开文件的函数,它将返回一个file对象。

这是何时应使用open的示例:

f = open(filename, 'r')
for line in f:
    process(line)
f.close()

这是何时应使用文件的示例:

class LoggingFile(file):
    def write(self, data):
        sys.stderr.write("Wrote %d bytes\n" % len(data))
        super(LoggingFile, self).write(data)

如您所见,存在两者的充分理由和明确的用例。

file() is a type, like an int or a list. open() is a function for opening files, and will return a file object.

This is an example of when you should use open:

f = open(filename, 'r')
for line in f:
    process(line)
f.close()

This is an example of when you should use file:

class LoggingFile(file):
    def write(self, data):
        sys.stderr.write("Wrote %d bytes\n" % len(data))
        super(LoggingFile, self).write(data)

As you can see, there’s a good reason for both to exist, and a clear use-case for both.


回答 3

在功能上,两者是相同的;无论如何open都会调用file,因此当前的区别在于样式。在Python文档建议使用open

打开文件时,最好使用open()而不是直接调用文件构造函数。

原因是在将来的版本中不能保证它们是相同的(open将成为工厂函数,根据其打开的路径返回不同类型的对象)。

Functionally, the two are the same; open will call file anyway, so currently the difference is a matter of style. The Python docs recommend using open.

When opening a file, it’s preferable to use open() instead of invoking the file constructor directly.

The reason is that in future versions they is not guaranteed to be the same (open will become a factory function, which returns objects of different types depending on the path it’s opening).


回答 4

仅使用open()打开文件。file()实际上在3.0中已被删除,目前不推荐使用。他们之间有一种奇怪的关系,但是file()现在正在进行中,因此不再需要担心。

以下来自Python 2.6文档。[括号内的内容]由我添加。

打开文件时,最好使用open()而不是直接调用此[file()]构造函数。文件更适合类型测试(例如,编写isinstance(f,file)

Only ever use open() for opening files. file() is actually being removed in 3.0, and it’s deprecated at the moment. They’ve had a sort of strange relationship, but file() is going now, so there’s no need to worry anymore.

The following is from the Python 2.6 docs. [bracket stuff] added by me.

When opening a file, it’s preferable to use open() instead of invoking this [file()] constructor directly. file is more suited to type testing (for example, writing isinstance(f, file)


回答 5

Van Rossum先生说,尽管open()当前是file()的别名,但您应该使用open(),因为将来可能会改变。

According to Mr Van Rossum, although open() is currently an alias for file() you should use open() because this might change in the future.


如何为具有多对多字段的Django模型创建对象?

问题:如何为具有多对多字段的Django模型创建对象?

我的模特:

class Sample(models.Model):
    users = models.ManyToManyField(User)

我想同时保存user1并保存user2在该模型中:

user1 = User.objects.get(pk=1)
user2 = User.objects.get(pk=2)
sample_object = Sample(users=user1, users=user2)
sample_object.save()

我知道这是错误的,但是我敢肯定,您会明白我的意思。你会怎么做?

My model:

class Sample(models.Model):
    users = models.ManyToManyField(User)

I want to save both user1 and user2 in that model:

user1 = User.objects.get(pk=1)
user2 = User.objects.get(pk=2)
sample_object = Sample(users=user1, users=user2)
sample_object.save()

I know that’s wrong, but I’m sure you get what I want to do. How would you do it ?


回答 0

您不能从未保存的对象创建m2m关系。如果有pk,请尝试以下操作:

sample_object = Sample()
sample_object.save()
sample_object.users.add(1,2)

更新:阅读了saverio的答案后,我决定对这个问题进行更深入的研究。这是我的发现。

这是我最初的建议。它可以工作,但不是最佳选择。(注意:我使用Bar的是s和a Foo而不是Users和a Sample,但是您知道了。)

bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars.add(bar1)
foo.bars.add(bar2)

它总共产生7个查询:

SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

我相信我们可以做得更好。您可以将多个对象传递给该add()方法:

bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars.add(bar1, bar2)

如我们所见,传递多个对象可以节省一个SELECT

SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

我不知道您还可以分配对象列表:

bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars = [bar1, bar2]

不幸的是,这又增加了一个SELECT

SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE "app_foo_bars"."foo_id" = 1
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

让我们尝试分配一个pks 列表,如saverio建议的那样:

foo = Foo()
foo.save()
foo.bars = [1,2]

由于不获取两个Bars,因此保存了两个SELECT语句,总共有5个:

INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE "app_foo_bars"."foo_id" = 1
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

最终获胜者是:

foo = Foo()
foo.save()
foo.bars.add(1,2)

路过pks到add()让我们一共有4个查询:

INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

You cannot create m2m relations from unsaved objects. If you have the pks, try this:

sample_object = Sample()
sample_object.save()
sample_object.users.add(1,2)

Update: After reading the saverio’s answer, I decided to investigate the issue a bit more in depth. Here are my findings.

This was my original suggestion. It works, but isn’t optimal. (Note: I’m using Bars and a Foo instead of Users and a Sample, but you get the idea).

bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars.add(bar1)
foo.bars.add(bar2)

It generates a whopping total of 7 queries:

SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

I’m sure we can do better. You can pass multiple objects to the add() method:

bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars.add(bar1, bar2)

As we can see, passing multiple objects saves one SELECT:

SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

I wasn’t aware that you can also assign a list of objects:

bar1 = Bar.objects.get(pk=1)
bar2 = Bar.objects.get(pk=2)
foo = Foo()
foo.save()
foo.bars = [bar1, bar2]

Unfortunately, that creates one additional SELECT:

SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 1
SELECT "app_bar"."id", "app_bar"."name" FROM "app_bar" WHERE "app_bar"."id" = 2
INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE "app_foo_bars"."foo_id" = 1
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

Let’s try to assign a list of pks, as saverio suggested:

foo = Foo()
foo.save()
foo.bars = [1,2]

As we don’t fetch the two Bars, we save two SELECT statements, resulting in a total of 5:

INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."id", "app_foo_bars"."foo_id", "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE "app_foo_bars"."foo_id" = 1
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

And the winner is:

foo = Foo()
foo.save()
foo.bars.add(1,2)

Passing pks to add() gives us a total of 4 queries:

INSERT INTO "app_foo" ("name") VALUES ()
SELECT "app_foo_bars"."bar_id" FROM "app_foo_bars" WHERE ("app_foo_bars"."foo_id" = 1  AND "app_foo_bars"."bar_id" IN (1, 2))
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 1)
INSERT INTO "app_foo_bars" ("foo_id", "bar_id") VALUES (1, 2)

回答 1

对于将来的访问者,您可以使用django 1.4中新的bulk_create2个查询中创建一个对象及其所有m2m对象。请注意,仅当您不需要对带有save()方法或信号的数据进行任何预处理或后处理时,此方法才可用。您插入的正是数据库中的内容

您无需在字段上指定“直通”模型即可执行此操作。为了完整起见,下面的示例创建了一个空白的Users模型来模仿原始海报的要求。

from django.db import models

class Users(models.Model):
    pass

class Sample(models.Model):
    users = models.ManyToManyField(Users)

现在,在Shell或其他代码中,创建2个用户,创建一个示例对象,然后将用户批量添加到该示例对象中。

Users().save()
Users().save()

# Access the through model directly
ThroughModel = Sample.users.through

users = Users.objects.filter(pk__in=[1,2])

sample_object = Sample()
sample_object.save()

ThroughModel.objects.bulk_create([
    ThroughModel(users_id=users[0].pk, sample_id=sample_object.pk),
    ThroughModel(users_id=users[1].pk, sample_id=sample_object.pk)
])

For future visitors, you can create an object and all of its m2m objects in 2 queries using the new bulk_create in django 1.4. Note that this is only usable if you don’t require any pre or post-processing on the data with save() methods or signals. What you insert is exactly what will be in the DB

You can do this without specifying a “through” model on the field. For completeness, the example below creates a blank Users model to mimic what the original poster was asking.

from django.db import models

class Users(models.Model):
    pass

class Sample(models.Model):
    users = models.ManyToManyField(Users)

Now, in a shell or other code, create 2 users, create a sample object, and bulk add the users to that sample object.

Users().save()
Users().save()

# Access the through model directly
ThroughModel = Sample.users.through

users = Users.objects.filter(pk__in=[1,2])

sample_object = Sample()
sample_object.save()

ThroughModel.objects.bulk_create([
    ThroughModel(users_id=users[0].pk, sample_id=sample_object.pk),
    ThroughModel(users_id=users[1].pk, sample_id=sample_object.pk)
])

回答 2

Django 1.9
一个简单的例子:

sample_object = Sample()
sample_object.save()

list_of_users = DestinationRate.objects.all()
sample_object.users.set(list_of_users)

Django 1.9
A quick example:

sample_object = Sample()
sample_object.save()

list_of_users = DestinationRate.objects.all()
sample_object.users.set(list_of_users)

回答 3

RelatedObjectManagers与Model中的字段是不同的“属性”。实现您想要的最简单的方法是

sample_object = Sample.objects.create()
sample_object.users = [1, 2]

这与分配用户列表相同,而没有其他查询和模型构建。

如果查询的数量让您感到困扰(而不是简单),那么最佳解决方案将需要三个查询:

sample_object = Sample.objects.create()
sample_id = sample_object.id
sample_object.users.through.objects.create(user_id=1, sample_id=sample_id)
sample_object.users.through.objects.create(user_id=2, sample_id=sample_id)

这将起作用,因为我们已经知道“用户”列表为空,因此我们可以轻松创建。

RelatedObjectManagers are different “attributes” than fields in a Model. The simplest way to achieve what you are looking for is

sample_object = Sample.objects.create()
sample_object.users = [1, 2]

That’s the same as assigning a User list, without the additional queries and the model building.

If the number of queries is what bothers you (instead of simplicity), then the optimal solution requires three queries:

sample_object = Sample.objects.create()
sample_id = sample_object.id
sample_object.users.through.objects.create(user_id=1, sample_id=sample_id)
sample_object.users.through.objects.create(user_id=2, sample_id=sample_id)

This will work because we already know that the ‘users’ list is empty, so we can create mindlessly.


回答 4

您可以通过以下方式替换相关对象集(Django 1.9中的新增功能):

new_list = [user1, user2, user3]
sample_object.related_set.set(new_list)

You could replace the set of related objects in this way (new in Django 1.9):

new_list = [user1, user2, user3]
sample_object.related_set.set(new_list)

回答 5

如果有人想做David Marbles,请回答自我引用ManyToMany字段。直通模型的ID称为:“ to_’model_name_id”和“ from_’model_name’_id”。

如果这样不起作用,您可以检查Django连接。

If someone is looking to do David Marbles answer on a self referring ManyToMany field. The ids of the through model are called: “to_’model_name_id” and “from_’model_name’_id”.

If that doesn’t work you can check the django connection.


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.


如何从macOS完全卸载Anaconda

问题:如何从macOS完全卸载Anaconda

如何从MacOS Sierra完全卸载Anaconda并恢复为原始Python?我试过使用,conda-clean -yes但不起作用。我也删除了其中的内容,~/.bash_profile但是它仍然使用Anaconda python,并且我仍然可以运行conda命令。

How can I completely uninstall Anaconda from MacOS Sierra and revert back to the original Python? I have tried using conda-clean -yes but that doesn’t work. I also remove the stuff in ~/.bash_profile but it still uses the Anaconda python and I can still run the conda command.


回答 0

删除配置:

conda install anaconda-clean
anaconda-clean --yes

删除配置后,您可以删除anaconda安装文件夹,该文件夹通常位于主目录下:

rm -rf ~/anaconda3

另外,该anaconda-clean --yes命令还会在您的主目录中以格式创建备份~/.anaconda_backup/<timestamp>。确保也删除该一个。


编辑(v5.2.0):现在,如果您要清除所有内容,则还必须删除添加到的最后两行.bash_profile。他们看着像是:

# added by Anaconda3 5.2.0 installer
export PATH="/Users/ody/anaconda3/bin:$PATH"

To remove the configs:

conda install anaconda-clean
anaconda-clean --yes

Once the configs are removed you can delete the anaconda install folder, which is usually under your home dir:

rm -rf ~/anaconda3

Also, the anaconda-clean --yes command creates a backup in your home directory of the format ~/.anaconda_backup/<timestamp>. Make sure to delete that one also.


EDIT (v5.2.0): Now if you want to clean all, you will also have to delete the two last lines added to your .bash_profile. They look like:

# added by Anaconda3 5.2.0 installer
export PATH="/Users/ody/anaconda3/bin:$PATH"

回答 1

要卸载Anaconda,请打开终端窗口:

  1. 删除整个anaconda安装目录:
rm -rf ~/anaconda
  1. 编辑~/.bash_profile 并从您的PATH环境变量中删除anaconda目录。

注意:您可能需要编辑.bashrc和/或.profile文件而不是.bash_profile

  1. 删除以下隐藏的文件和目录,这些文件和目录可能是在主目录中创建的:

    • .condarc
    • .conda
    • .continuum

用:

rm -rf ~/.condarc ~/.conda ~/.continuum

To uninstall Anaconda open a terminal window:

  1. Remove the entire anaconda installation directory:
rm -rf ~/anaconda
  1. Edit ~/.bash_profile and remove the anaconda directory from your PATH environment variable.

Note: You may need to edit .bashrc and/or .profile files instead of .bash_profile

  1. Remove the following hidden files and directories, which may have been created in the home directory:

    • .condarc
    • .conda
    • .continuum

Use:

rm -rf ~/.condarc ~/.conda ~/.continuum

回答 2

就我而言(Mac High Sierra),它安装在〜/ opt / anaconda3上。

https://docs.anaconda.com/anaconda/install/uninstall/

In my case (Mac High Sierra) it was installed at ~/opt/anaconda3.

https://docs.anaconda.com/anaconda/install/uninstall/


回答 3

打开终端,并输入以下命令,删除整个Anaconda目录,该目录的名称将为“ anaconda2”或“ anaconda3”,例如:rm -rf〜/ anaconda3。然后使用命令“ conda uninstall” https://conda.io/docs/commands/conda-uninstall.html删除conda 。

Open the terminal and remove your entire Anaconda directory, which will have a name such as “anaconda2” or “anaconda3”, by entering the following command: rm -rf ~/anaconda3. Then remove conda with command “conda uninstall” https://conda.io/docs/commands/conda-uninstall.html.


回答 4

这是anaconda在删除Anaconda之后有一个条目破坏了我的python安装的地方。希望这对其他人有帮助。

如果您使用的是纱,我在〜/“用户名”的.yarn.rc文件中找到了此条目

python“ / Users / someone / anaconda3 / bin / python3”

删除此行固定了彻底删除所需的最后一个位置。我不确定如何添加该条目,但它有帮助

This is one more place that anaconda had an entry that was breaking my python install after removing Anaconda. Hoping this helps someone else.

If you are using yarn, I found this entry in my .yarn.rc file in ~/”username”

python “/Users/someone/anaconda3/bin/python3”

removing this line fixed one last place needed for complete removal. I am not sure how that entry was added but it helped


回答 5

在执行了辣木和jkysam的非常有用的建议而没有立即获得成功后,需要简单地重新启动Mac才能使系统识别出更改。希望这对某人有帮助!

After performing the very helpful suggestions from both spicyramen & jkysam without immediate success, a simple restart of my Mac was needed to make the system recognize the changes. Hope this helps someone!


回答 6

这对我有用:

conda remove --all --prefix /Users/username/anaconda/bin/python

然后从.bash_profile中的$ PATH中删除

This has worked for me:

conda remove --all --prefix /Users/username/anaconda/bin/python

then also remove from $PATH in .bash_profile


回答 7

在我的〜/ .bash_profile文件中添加export PATH="/Users/<username>/anaconda/bin:$PATH"(或export PATH="/Users/<username>/anaconda3/bin:$PATH"如果您有anaconda 3),可以为我解决此问题。

Adding export PATH="/Users/<username>/anaconda/bin:$PATH" (or export PATH="/Users/<username>/anaconda3/bin:$PATH" if you have anaconda 3) to my ~/.bash_profile file, fixed this issue for me.


回答 8

官方说明似乎在这里:https : //docs.anaconda.com/anaconda/install/uninstall/

但是,如果您喜欢我,由于某种原因而无法使用,并且由于某种原因您的conda却安装在其他地方,并告诉您这样做:

rm -rf ~/opt

我不知道为什么将它保存在那里,但这就是我的目的。


这对我修复conda安装很有用(如果这是您像我这样首先卸载它的原因):https : //stackoverflow.com/a/60902863/1601580最后为我修复了它。不知道为什么conda首先表现得很怪异,或者为什么错误地首先把东西安装了……

The official instructions seem to be here: https://docs.anaconda.com/anaconda/install/uninstall/

but if you like me that didn’t work for some reason and for some reason your conda was installed somewhere else with telling you do this:

rm -rf ~/opt

I have no idea why it was saved there but that’s what did it for me.


This was useful to me in fixing my conda installation (if that is the reason you are uninstalling it in the first place like me): https://stackoverflow.com/a/60902863/1601580 that ended up fixing it for me. Not sure why conda was acting weird in the first place or installing things wrongly in the first place though…


ImportError:没有名为bs4的模块(BeautifulSoup)

问题:ImportError:没有名为bs4的模块(BeautifulSoup)

我正在使用Python并使用Flask。当我在计算机上运行我的主Python文件时,它可以正常运行,但是当我激活venv并在终端中运行Flask Python文件时,它表示我的主Python文件具有“没有名为bs4的模块”。任何意见或建议,不胜感激。

I’m working in Python and using Flask. When I run my main Python file on my computer, it works perfectly, but when I activate venv and run the Flask Python file in the terminal, it says that my main Python file has “No Module Named bs4.” Any comments or advice is greatly appreciated.


回答 0

激活virtualenv,然后安装BeautifulSoup4:

$ pip install BeautifulSoup4

当您安装bs4使用easy_install,您在系统范围内进行了安装。因此,您的系统python可以导入它,但您的virtualenv python不能导入。如果您不需要bs4在系统python路径中安装,请卸载它并将其保留在virtualenv中。

有关virtualenvs的更多信息,请阅读此内容

Activate the virtualenv, and then install BeautifulSoup4:

$ pip install BeautifulSoup4

When you installed bs4 with easy_install, you installed it system-wide. So your system python can import it, but not your virtualenv python. If you do not need bs4 to be installed in your system python path, uninstall it and keep it in your virtualenv.

For more information about virtualenvs, read this


回答 1

对于python2.x

sudo pip install BeautifulSoup4

对于python3

sudo apt-get install python3-bs4

For python2.x:

sudo pip install BeautifulSoup4

For python3:

sudo apt-get install python3-bs4

回答 2

只需标记Balthazar的答案即可。跑步

pip install BeautifulSoup4

没有为我工作。改为使用

pip install beautifulsoup4

Just tagging onto Balthazar’s answer. Running

pip install BeautifulSoup4

did not work for me. Instead use

pip install beautifulsoup4

回答 3

pip3 install BeautifulSoup4

试试这个。这个对我有用。原因在这里得到了很好的解释..

pip3 install BeautifulSoup4

Try this. It works for me. The reason is well explained here..


回答 4

如果您将Anaconda用于软件包管理,则应执行以下操作:

conda install -c anaconda beautifulsoup4

If you are using Anaconda for package management, following should do:

conda install -c anaconda beautifulsoup4


回答 5

如果您使用Pycharm,请转到preferences - project interpreter - install bs4

如果尝试安装BeautifulSoup,它将仍然显示没有名为的模块bs4

If you use Pycharm, go to preferences - project interpreter - install bs4.

If you try to install BeautifulSoup, it will still show that no module named bs4.


回答 6

我建议您使用以下命令来卸载bs4库:

pip卸载bs4

然后使用以下命令进行安装:

须藤apt-get install python3-bs4

当我使用以下命令安装bs4库时,在Linux Ubuntu中遇到了相同的问题:

点安装bs4

I will advise you to uninstall the bs4 library by using this command:

pip uninstall bs4

and then install it using this command:

sudo apt-get install python3-bs4

I was facing the same problem in my Linux Ubuntu when I used the following command for installing bs4 library:

pip install bs4


回答 7

试试这个:

sudo python3 -m pip install bs4

Try this:

sudo python3 -m pip install bs4

回答 8

pip install --user BeautifulSoup4

pip install --user BeautifulSoup4


回答 9

pip3.7 install bs4

试试这个。它适用于python 3.7

pip3.7 install bs4

Try this. It works with python 3.7


回答 10

我做了@ rayid-ali所说的,除了我在Windows 10机器上,所以我省略了sudo。也就是说,我做了以下工作:

python3 -m pip install bs4

它就像一个pycharm。无论如何都像魅力一样工作。

I did what @rayid-ali said, except I’m on a Windows 10 machine so I left out the sudo. That is, I did the following:

python3 -m pip install bs4

and it worked like a pycharm. Worked like a charm anyway.


回答 11

最简单的是使用easy_install。

easy_install bs4 

如果pip失败,它将起作用。

The easiest is using easy_install.

easy_install bs4 

It will work if pip fails.


回答 12

很多针对Python 2编写的教程/参考资料都告诉您使用pip install somename。如果您使用的是Python 3,则要将其更改为pip3 install somename。

A lot of tutorials/references were written for Python 2 and tell you to use pip install somename. If you’re using Python 3 you want to change that to pip3 install somename.


回答 13

您可能想尝试使用安装bs4

pip install --ignore-installed BeautifulSoup4

如果上述方法不适合您。

You might want to try install bs4 with

pip install --ignore-installed BeautifulSoup4

if the methods above didn’t work for you.


回答 14

尝试重新安装模块,或者尝试使用以下命令与漂亮的汤一起安装

pip install --ignore-installed BeautifulSoup4

Try reinstalling the module OR Try installing with beautiful soup with the below command

pip install --ignore-installed BeautifulSoup4

回答 15

原始查询的附录:modules.py

help('modules')

$python modules.py

它列出了已经安装的模块bs4。

_codecs_kr          blinker             json                six
_codecs_tw          brotli              kaitaistruct        smtpd
_collections        bs4                 keyword             smtplib
_collections_abc    builtins            ldap3               sndhdr
_compat_pickle      bz2                 lib2to3             socket

正确的解决方案是:

pip install --upgrade bs4

应该解决问题。

不仅如此,其他模块也会显示相同的错误。因此,对于那些错误的模块,您必须以与上述相同的方式发出pip命令。

Addendum to the original query: modules.py

help('modules')

$python modules.py

It lists that module bs4 already been installed.

_codecs_kr          blinker             json                six
_codecs_tw          brotli              kaitaistruct        smtpd
_collections        bs4                 keyword             smtplib
_collections_abc    builtins            ldap3               sndhdr
_compat_pickle      bz2                 lib2to3             socket

Proper solution is:

pip install --upgrade bs4

Should solve the problem.

Not only that, it will show same error for other modules as well. So you got to issue the pip command same way as above for those errored module(s).


如何使用python从数组中删除特定元素

问题:如何使用python从数组中删除特定元素

我想写一些东西从数组中删除一个特定的元素。我知道我必须for遍历数组以查找与内容匹配的元素。

假设我有一组电子邮件,并且想摆脱与某些电子邮件字符串匹配的元素。

我实际上想使用for循环结构,因为我还需要对其他数组使用相同的索引。

这是我的代码:

for index, item in emails:
    if emails[index] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

I want to write something that removes a specific element from an array. I know that I have to for loop through the array to find the element that matches the content.

Let’s say that I have an array of emails and I want to get rid of the element that matches some email string.

I’d actually like to use the for loop structure because I need to use the same index for other arrays as well.

Here is the code that I have:

for index, item in emails:
    if emails[index] == 'something@something.com':
         emails.pop(index)
         otherarray.pop(index)

回答 0

您不需要迭代数组。只是:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

这将删除与字符串匹配的第一次出现。

编辑:编辑后,您仍然不需要迭代。做就是了:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]

You don’t need to iterate the array. Just:

>>> x = ['ala@ala.com', 'bala@bala.com']
>>> x
['ala@ala.com', 'bala@bala.com']
>>> x.remove('ala@ala.com')
>>> x
['bala@bala.com']

This will remove the first occurence that matches the string.

EDIT: After your edit, you still don’t need to iterate over. Just do:

index = initial_list.index(item1)
del initial_list[index]
del other_list[index]

回答 1

使用filter()and lambda将提供一种简洁的方法来删除不需要的值:

newEmails = list(filter(lambda x : x != 'something@something.com', emails))

这不会修改电子邮件。它创建新列表newEmails,其中仅包含匿名函数为其返回True的元素。

Using filter() and lambda would provide a neat and terse method of removing unwanted values:

newEmails = list(filter(lambda x : x != 'something@something.com', emails))

This does not modify emails. It creates the new list newEmails containing only elements for which the anonymous function returned True.


回答 2

如果需要在for循环中使用索引,则for循环不正确:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

对于您而言,Bogdan解决方案是可以的,但是您选择的数据结构不是很好。必须用来自一个的数据与来自另一个的数据以相同的索引来维护这两个列表是笨拙的。

最好使用连音(电子邮件,其他数据)列表,或者以电子邮件为键的字典。

Your for loop is not right, if you need the index in the for loop use:

for index, item in enumerate(emails):
    # whatever (but you can't remove element while iterating)

In your case, Bogdan solution is ok, but your data structure choice is not so good. Having to maintain these two lists with data from one related to data from the other at same index is clumsy.

A list of tupple (email, otherdata) may be better, or a dict with email as key.


回答 3

做到这一点的理智方法是使用zip()和List Comprehension / Generator表达式:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == 'something@something.com')

new_emails, new_other_list = zip(*filtered)

另外,如果您未使用array.array()numpy.array(),那么很可能您正在使用[]list(),这会为您提供列表,而不是数组。不一样的东西。

The sane way to do this is to use zip() and a List Comprehension / Generator Expression:

filtered = (
    (email, other) 
        for email, other in zip(emails, other_list) 
            if email == 'something@something.com')

new_emails, new_other_list = zip(*filtered)

Also, if your’e not using array.array() or numpy.array(), then most likely you are using [] or list(), which give you Lists, not Arrays. Not the same thing.


回答 4

有一个替代解决方案,该问题还处理重复的匹配项。

我们先从相同长度的2所列出:emailsotherarray。目的是从两个列表中的每个索引i中删除项目emails[i] == 'something@something.com'

这可以使用列表理解,然后通过以下方式实现zip

emails = ['abc@def.com', 'something@something.com', 'ghi@jkl.com']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= 'something@something.com']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['abc@def.com', 'ghi@jkl.com']
print(otherarray)  # ['some', 'details']

There is an alternative solution to this problem which also deals with duplicate matches.

We start with 2 lists of equal length: emails, otherarray. The objective is to remove items from both lists for each index i where emails[i] == 'something@something.com'.

This can be achieved using a list comprehension and then splitting via zip:

emails = ['abc@def.com', 'something@something.com', 'ghi@jkl.com']
otherarray = ['some', 'other', 'details']

from operator import itemgetter

res = [(i, j) for i, j in zip(emails, otherarray) if i!= 'something@something.com']
emails, otherarray = map(list, map(itemgetter(0, 1), zip(*res)))

print(emails)      # ['abc@def.com', 'ghi@jkl.com']
print(otherarray)  # ['some', 'details']

有趣好用的Python教程

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