分类目录归档:知识问答

如何在NumPy中创建一个空数组/矩阵?

问题:如何在NumPy中创建一个空数组/矩阵?

我无法弄清楚如何以通常使用列表的方式使用数组或矩阵。我想创建一个空数组(或矩阵),然后一次向其中添加一列(或行)。

目前,我能找到的唯一方法是:

mat = None
for col in columns:
    if mat is None:
        mat = col
    else:
        mat = hstack((mat, col))

而如果这是一个列表,我会做这样的事情:

list = []
for item in data:
    list.append(item)

有没有办法对NumPy数组或矩阵使用这种表示法?

I can’t figure out how to use an array or matrix in the way that I would normally use a list. I want to create an empty array (or matrix) and then add one column (or row) to it at a time.

At the moment the only way I can find to do this is like:

mat = None
for col in columns:
    if mat is None:
        mat = col
    else:
        mat = hstack((mat, col))

Whereas if it were a list, I’d do something like this:

list = []
for item in data:
    list.append(item)

Is there a way to use that kind of notation for NumPy arrays or matrices?


回答 0

您对有效使用NumPy的思维模式有误。NumPy数组存储在连续的内存块中。如果要向现有阵列添加行或列,则需要将整个阵列复制到新的内存块中,从而为要存储的新元素创建间隙。如果反复进行以构建阵列,则效率非常低下。

在添加行的情况下,最好的选择是创建一个与数据集最终大小一样大的数组,然后逐行向其中添加数据:

>>> import numpy
>>> a = numpy.zeros(shape=(5,2))
>>> a
array([[ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])
>>> a[0] = [1,2]
>>> a[1] = [2,3]
>>> a
array([[ 1.,  2.],
   [ 2.,  3.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])

You have the wrong mental model for using NumPy efficiently. NumPy arrays are stored in contiguous blocks of memory. If you want to add rows or columns to an existing array, the entire array needs to be copied to a new block of memory, creating gaps for the new elements to be stored. This is very inefficient if done repeatedly to build an array.

In the case of adding rows, your best bet is to create an array that is as big as your data set will eventually be, and then assign data to it row-by-row:

>>> import numpy
>>> a = numpy.zeros(shape=(5,2))
>>> a
array([[ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])
>>> a[0] = [1,2]
>>> a[1] = [2,3]
>>> a
array([[ 1.,  2.],
   [ 2.,  3.],
   [ 0.,  0.],
   [ 0.,  0.],
   [ 0.,  0.]])

回答 1

NumPy数组是与列表非常不同的数据结构,旨在以不同的方式使用。您的使用hstack可能效率很低…每次调用它时,现有数组中的所有数据都将被复制到一个新数组中。(该append函数会有相同的问题。)如果您想一次建立一列矩阵,最好将其保留在列表中直到完成,然后再将其转换为数组。

例如


mylist = []
for item in data:
    mylist.append(item)
mat = numpy.array(mylist)

item可以是列表,数组或任何可迭代的,只要每个item元素具有相同数量的元素即可。
在这种特殊情况下(data保存矩阵列有些可迭代),您可以简单地使用


mat = numpy.array(data)

(还请注意,将其list用作变量名可能不是一个好习惯,因为它会用该名称掩盖内置类型,这可能会导致错误。)

编辑:

如果出于某种原因您确实想创建一个空数组,则可以使用 numpy.array([]),但这很少有用!

A NumPy array is a very different data structure from a list and is designed to be used in different ways. Your use of hstack is potentially very inefficient… every time you call it, all the data in the existing array is copied into a new one. (The append function will have the same issue.) If you want to build up your matrix one column at a time, you might be best off to keep it in a list until it is finished, and only then convert it into an array.

e.g.


mylist = []
for item in data:
    mylist.append(item)
mat = numpy.array(mylist)

item can be a list, an array or any iterable, as long as each item has the same number of elements.
In this particular case (data is some iterable holding the matrix columns) you can simply use


mat = numpy.array(data)

(Also note that using list as a variable name is probably not good practice since it masks the built-in type by that name, which can lead to bugs.)

EDIT:

If for some reason you really do want to create an empty array, you can just use numpy.array([]), but this is rarely useful!


回答 2

要在NumPy中创建一个空的多维数组(例如,m*n用于存储矩阵的2D数组),以防万一您不知道m要追加多少行并且不在乎Stephen Simmons提到的计算成本(即重新构建数组),您可以将要附加到的尺寸压缩为0 X = np.empty(shape=[0, n])

例如,您可以使用这种方式(在这里m = 5我们假设在创建空矩阵时我们并不知道,以及n = 2):

import numpy as np

n = 2
X = np.empty(shape=[0, n])

for i in range(5):
    for j  in range(2):
        X = np.append(X, [[i, j]], axis=0)

print X

这将为您提供:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]

To create an empty multidimensional array in NumPy (e.g. a 2D array m*n to store your matrix), in case you don’t know m how many rows you will append and don’t care about the computational cost Stephen Simmons mentioned (namely re-buildinging the array at each append), you can squeeze to 0 the dimension to which you want to append to: X = np.empty(shape=[0, n]).

This way you can use for example (here m = 5 which we assume we didn’t know when creating the empty matrix, and n = 2):

import numpy as np

n = 2
X = np.empty(shape=[0, n])

for i in range(5):
    for j  in range(2):
        X = np.append(X, [[i, j]], axis=0)

print X

which will give you:

[[ 0.  0.]
 [ 0.  1.]
 [ 1.  0.]
 [ 1.  1.]
 [ 2.  0.]
 [ 2.  1.]
 [ 3.  0.]
 [ 3.  1.]
 [ 4.  0.]
 [ 4.  1.]]

回答 3

我进行了很多研究,因为我需要在我的一个学校项目中使用numpy.array作为集合,并且需要将其初始化为空。在这里,我在Stack Overflow上没有找到任何相关的答案,所以我开始涂鸦的东西。

# Initialize your variable as an empty list first
In [32]: x=[]
# and now cast it as a numpy ndarray
In [33]: x=np.array(x)

结果将是:

In [34]: x
Out[34]: array([], dtype=float64)

因此,您可以按如下所示直接初始化np数组:

In [36]: x= np.array([], dtype=np.float64)

我希望这有帮助。

I looked into this a lot because I needed to use a numpy.array as a set in one of my school projects and I needed to be initialized empty… I didn’t found any relevant answer here on Stack Overflow, so I started doodling something.

# Initialize your variable as an empty list first
In [32]: x=[]
# and now cast it as a numpy ndarray
In [33]: x=np.array(x)

The result will be:

In [34]: x
Out[34]: array([], dtype=float64)

Therefore you can directly initialize an np array as follows:

In [36]: x= np.array([], dtype=np.float64)

I hope this helps.


回答 4

您可以使用附加功能。对于行:

>>> from numpy import *
>>> a = array([10,20,30])
>>> append(a, [[1,2,3]], axis=0)
array([[10, 20, 30],      
       [1, 2, 3]])

对于列:

>>> append(a, [[15],[15]], axis=1)
array([[10, 20, 30, 15],      
       [1, 2, 3, 15]])

编辑
当然,正如其他答案中所述,除非每次对矩阵/数组进行一些处理(例如反转),否则每次将其添加到列表中时,我都会创建一个列表,将其添加到列表中,然后将其转换为数组。

You can use the append function. For rows:

>>> from numpy import *
>>> a = array([10,20,30])
>>> append(a, [[1,2,3]], axis=0)
array([[10, 20, 30],      
       [1, 2, 3]])

For columns:

>>> append(a, [[15],[15]], axis=1)
array([[10, 20, 30, 15],      
       [1, 2, 3, 15]])

EDIT
Of course, as mentioned in other answers, unless you’re doing some processing (ex. inversion) on the matrix/array EVERY time you append something to it, I would just create a list, append to it then convert it to an array.


回答 5

如果您完全不知道数组的最终大小,则可以像这样增加数组的大小:

my_arr = numpy.zeros((0,5))
for i in range(3):
    my_arr=numpy.concatenate( ( my_arr, numpy.ones((1,5)) ) )
print(my_arr)

[[ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]]
  • 注意0第一行中的。
  • numpy.append是另一种选择。它调用numpy.concatenate

If you absolutely don’t know the final size of the array, you can increment the size of the array like this:

my_arr = numpy.zeros((0,5))
for i in range(3):
    my_arr=numpy.concatenate( ( my_arr, numpy.ones((1,5)) ) )
print(my_arr)

[[ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]  [ 1.  1.  1.  1.  1.]]
  • Notice the 0 in the first line.
  • numpy.append is another option. It calls numpy.concatenate.

回答 6

您可以将其应用于构建任何类型的数组,例如零:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]

You can apply it to build any kind of array, like zeros:

a = range(5)
a = [i*0 for i in a]
print a 
[0, 0, 0, 0, 0]

回答 7

这是一些使numpys看起来更像列表的解决方法

np_arr = np.array([])
np_arr = np.append(np_arr , 2)
np_arr = np.append(np_arr , 24)
print(np_arr)

输出:array([2.,24.])

Here is some workaround to make numpys look more like Lists

np_arr = np.array([])
np_arr = np.append(np_arr , 2)
np_arr = np.append(np_arr , 24)
print(np_arr)

OUTPUT: array([ 2., 24.])


回答 8

根据您使用它的目的,您可能需要指定数据类型(请参见‘dtype’)。

例如,要创建一个8位值的2D数组(适合用作单色图像):

myarray = numpy.empty(shape=(H,W),dtype='u1')

对于RGB图像,在形状中包括颜色通道的数量: shape=(H,W,3)

您可能还想考虑使用零初始化,numpy.zeros而不是使用numpy.empty。请参阅此处的注释。

Depending on what you are using this for, you may need to specify the data type (see ‘dtype’).

For example, to create a 2D array of 8-bit values (suitable for use as a monochrome image):

myarray = numpy.empty(shape=(H,W),dtype='u1')

For an RGB image, include the number of color channels in the shape: shape=(H,W,3)

You may also want to consider zero-initializing with numpy.zeros instead of using numpy.empty. See the note here.


回答 9

我认为您想处理列表的大部分工作,然后将结果用作矩阵。也许这是一种方式;

ur_list = []
for col in columns:
    ur_list.append(list(col))

mat = np.matrix(ur_list)

I think you want to handle most of the work with lists then use the result as a matrix. Maybe this is a way ;

ur_list = []
for col in columns:
    ur_list.append(list(col))

mat = np.matrix(ur_list)

回答 10

我认为您可以创建空的numpy数组,例如:

>>> import numpy as np
>>> empty_array= np.zeros(0)
>>> empty_array
array([], dtype=float64)
>>> empty_array.shape
(0,)

当您要在循环中附加numpy数组时,此格式很有用。

I think you can create empty numpy array like:

>>> import numpy as np
>>> empty_array= np.zeros(0)
>>> empty_array
array([], dtype=float64)
>>> empty_array.shape
(0,)

This format is useful when you want to append numpy array in the loop.


回答 11

为了创建一个空的NumPy数组而不定义其形状,有一种方法:

1。

arr = np.array([]) 

首选。因为您知道您将以numpy的形式使用它。

2。

arr = []
# and use it as numpy. append to it or etc..

NumPy之后将其转换为np.ndarray类型,无需额外的操作[] dimionsion

For creating an empty NumPy array without defining its shape there is to way:

1.

arr = np.array([]) 

preferred. cause you know you will be using this as numpy.

2.

arr = []
# and use it as numpy. append to it or etc..

NumPy converts this to np.ndarray type afterward, without extra [] dimionsion.


如何使用pip安装Python MySQLdb模块?

问题:如何使用pip安装Python MySQLdb模块?

如何使用pip为Python 安装MySQLdb模块?

How can I install the MySQLdb module for Python using pip?


回答 0

这很容易,但是很难记住正确的拼写:

pip install mysqlclient

如果您需要1.2.x版本(仅限旧版Python),请使用 pip install MySQL-python

注意:运行上述命令时,某些依赖项可能必须存在。关于如何在各种平台上安装这些的一些提示:

Ubuntu 14,Ubuntu 16,Debian 8.6(jessie)

sudo apt-get install python-pip python-dev libmysqlclient-dev

Fedora 24:

sudo dnf install python python-devel mysql-devel redhat-rpm-config gcc

苹果系统

brew install mysql-connector-c

如果失败,请尝试

brew install mysql

It’s easy to do, but hard to remember the correct spelling:

pip install mysqlclient

If you need 1.2.x versions (legacy Python only), use pip install MySQL-python

Note: Some dependencies might have to be in place when running the above command. Some hints on how to install these on various platforms:

Ubuntu 14, Ubuntu 16, Debian 8.6 (jessie)

sudo apt-get install python-pip python-dev libmysqlclient-dev

Fedora 24:

sudo dnf install python python-devel mysql-devel redhat-rpm-config gcc

Mac OS

brew install mysql-connector-c

if that fails, try

brew install mysql

回答 1

从全新的Ubuntu 14.04.2系统开始,需要以下两个命令:

 apt-get install python-dev libmysqlclient-dev
 pip install MySQL-python

仅仅进行“ pip安装”是行不通的。

http://codeinthehole.com/writing/how-to-set-up-mysql-for-python-on-ubuntu/

Starting from a fresh Ubuntu 14.04.2 system, these two commands were needed:

 apt-get install python-dev libmysqlclient-dev
 pip install MySQL-python

Just doing the “pip install” by itself did not work.

From http://codeinthehole.com/writing/how-to-set-up-mysql-for-python-on-ubuntu/


回答 2

第一

pip install pymysql

然后将下面的代码放入__init__.pyprojectname/__init__.py

import pymysql
pymysql.install_as_MySQLdb()

我的环境是(python3.5,django1.10),此解决方案对我有用!

希望这可以帮助!!

First

pip install pymysql

Then put the code below into __init__.py (projectname/__init__.py)

import pymysql
pymysql.install_as_MySQLdb()

My environment is (python3.5, django1.10) and this solution works for me!

Hope this helps!!


回答 3

我在通过Pip(问题编译源)在Windows上安装64位版本的MySQLdb时遇到问题[安装32位版本就可以了]。设法从http://www.lfd.uci.edu/~gohlke/pythonlibs/上的.whl文件安装已编译的MySQLdb

然后可以通过pip将.whl文件作为文档安装在https://pip.pypa.io/en/latest/user_guide/#installing-from-wheels中

例如,如果您保存在中,C:/则可以通过

pip install c:/MySQL_python-1.2.5-cp27-none-win_amd64.whl

后续行动:如果您安装了64位版本的Python,那么您想通过上面的链接安装64位AMD版本的MySQLdb [即,即使您具有Intel处理器]。如果您改为尝试安装32位版本,我认为您会在下面的注释中得到不受支持的滚轮错误。

I had problems installing the 64-bit version of MySQLdb on Windows via Pip (problem compiling sources) [32bit version installed ok]. Managed to install the compiled MySQLdb from the .whl file available from http://www.lfd.uci.edu/~gohlke/pythonlibs/

The .whl file can then be installed via pip as document in https://pip.pypa.io/en/latest/user_guide/#installing-from-wheels

For example if you save in C:/ the you can install via

pip install c:/MySQL_python-1.2.5-cp27-none-win_amd64.whl

Follow-up: if you have a 64bit version of Python installed, then you want to install the 64-bit AMD version of MySQLdb from the link above [i.e. even if you have a Intel processor]. If you instead try and install the 32-bit version, I think you get the unsupported wheel error in comments below.


回答 4

这对我有用:

pip install mysqlclient

这是针对python 3.x

well this worked for me:

pip install mysqlclient

this is for python 3.x


回答 5

我尝试了所有选项,但无法使其在Redhat平台上运行。我做了以下工作以使其工作:-

yum install MySQL-python -y

安装软件包后,便可以按照解释器中的说明导入模块:-

>>> import MySQLdb
>>> 

I tried all the option but was not able to get it working on Redhat platform. I did the following to make it work:-

yum install MySQL-python -y

Once the package was installed was able to import module as follows in the interpreter:-

>>> import MySQLdb
>>> 

回答 6

转到pycharm,然后转到默认设置-> pip(双击)-pymsqldb ..–>安装-在类似这样的程序中安装使用后

import pymysql as MySQLdb

# Open database connection
db = MySQLdb.connect("localhost","root","root","test" )

# prepare a cursor object using cursor() method
cursor = db.cursor()

# execute SQL query using execute() method.
cursor.execute("show tables")

# Fetch a single row using fetchone() method.
data = cursor.fetchall()
print (data)

# disconnect from server
db.close()

Go to pycharm then go to default setting –> pip (double click) — pymsqldb..– > install –after installing use in a program like this

import pymysql as MySQLdb

# Open database connection
db = MySQLdb.connect("localhost","root","root","test" )

# prepare a cursor object using cursor() method
cursor = db.cursor()

# execute SQL query using execute() method.
cursor.execute("show tables")

# Fetch a single row using fetchone() method.
data = cursor.fetchall()
print (data)

# disconnect from server
db.close()

回答 7

如果您使用的是Raspberry Pi [Raspbian OS]

首先需要有install pip命令

apt-get install python-pip

这样就可以依次安装

apt-get install python-dev libmysqlclient-dev

apt-get install python-pip

pip install MySQL-python

If you are use Raspberry Pi [Raspbian OS]

There are need to be install pip command at first

apt-get install python-pip

So that just install Sequently

apt-get install python-dev libmysqlclient-dev

apt-get install python-pip

pip install MySQL-python

回答 8

在此处输入图片说明

您可以访问此网站下载软件包。

enter image description here

You can go to this website to download the package.


回答 9

如果您无法安装mysqlclient,也可以安装pymysql

pip install pymysql

这与MySqldb相同。之后,使用pymysql代替MySQLdb

If you are unable to install mysqlclient you can also install pymysql:

pip install pymysql

This works same as MySqldb. After that use pymysql all over instead of MySQLdb


回答 10

我也遇到了同样的问题。如果您使用的是Windows,请按照以下步骤操作。转至:1.我的电脑2.系统属性3.高级系统设置4.在“高级”选项卡上,单击显示“环境变量”的按钮。5.然后在系统变量下,您必须添加/更改以下变量:PYTHONPATH和路径。这是我的变量的样子的粘贴信息:python path:

C:\Python27;C:\Python27\Lib\site-packages;C:\Python27\Lib;C:\Python27\DLLs;C:\Python27\Lib\lib-tk;C:\Python27\Scripts

路径:

C:\Program Files\MySQL\MySQL Utilities 1.3.5\;C:\Python27;C:\Python27\Lib\site-packages;C:\Python27\Lib;C:\Python27\DLLs;C:\Python27\Lib\lib-tk;C:\Python27\Scripts

看到这个 链接以供参考

I had the same problem too.Follow these steps if you are on Windows. Go to: 1.My Computer 2.System Properties 3.Advance System Settings 4. Under the “Advanced” tab click the button that says “Environment Variables” 5. Then under System Variables you have to add / change the following variables: PYTHONPATH and Path. Here is a paste of what my variables look like: python path:

C:\Python27;C:\Python27\Lib\site-packages;C:\Python27\Lib;C:\Python27\DLLs;C:\Python27\Lib\lib-tk;C:\Python27\Scripts

path:

C:\Program Files\MySQL\MySQL Utilities 1.3.5\;C:\Python27;C:\Python27\Lib\site-packages;C:\Python27\Lib;C:\Python27\DLLs;C:\Python27\Lib\lib-tk;C:\Python27\Scripts

See this link for reference


回答 11

上面的答案很好,但是当我们使用pip在Windows中安装MySQL-python时可能会出现一些问题

例如,它需要一些与Visual Stdio相关的文件。一个解决方案是安装VS2008或2010……显然,这太昂贵了。

另一种方法是@ bob90937的答案。我在这里要做一些补充。

使用http://www.lfd.uci.edu/~gohlke/pythonlibs,您可以下载许多科学开源扩展包的Windows二进制文件,以用于Python编程语言的官方CPython发行版。

返回主题,我们可以选择MySQL-python(py2)Mysqlclient(py3) 并使用pip install 进行安装。它给我们带来了极大的便利!

The above answer is great, but there may be some problems when we using pip to install MySQL-python in Windows

for example,It needs some files that are associated with Visual Stdio .One solution is installing VS2008 or 2010……Obviously,it cost too much.

Another way is the answer of @bob90937 . I am here to do something to add.

with http://www.lfd.uci.edu/~gohlke/pythonlibs, u can download many Windows binaries of many scientific open-source extension packages for the official CPython distribution of the Python programming language.

Back to topic,we can choose the MySQL-python(py2) or Mysqlclient(py3) and use pip install to install. it gives us Great convenience!


回答 12

对于Python3,我需要这样做:

python3 -m pip install MySQL

For Python3 I needed to do this:

python3 -m pip install MySQL

回答 13


回答 14

在RHEL 7上:

sudo yum install yum-utils mariadb-devel python-pip python-devel gcc

sudo /bin/pip2 install MySQL-python

on RHEL 7:

sudo yum install yum-utils mariadb-devel python-pip python-devel gcc

sudo /bin/pip2 install MySQL-python


回答 15

如果您的系统上安装了Windows,请在cmd上键入以下命令:

pip install mysql-connector

如果以上命令不起作用,请尝试使用:

pip install mysql-connector-python

现在,如果上述命令无法完成工作,请尝试使用:

pip install mysql-connector-python-rf

就是这样,您现在就可以走了。

If you have Windows installed on your system then type the following command on cmd :

pip install mysql-connector

if the above command does not work try using:

pip install mysql-connector-python

Now,if the above commands do not get the work done, try using:

pip install mysql-connector-python-rf

That’s it you are good to go now.


回答 16

这里给出的许多答案都相当令人困惑,因此我将尝试简单地说一下。它帮助我安装了这个

pip install pymysql

然后在python文件中使用以下命令

import pymysql as MySQLdb

这样,您可以毫无问题地使用MySQLdb。

Many of the given answers here are quite confusing so I will try to put it simply. It helped me to install this

pip install pymysql

and then use the following command in the python file

import pymysql as MySQLdb

This way you can use MySQLdb without any problems.


回答 17

如果pip3不起作用,您可以尝试:

sudo apt install python3-mysqldb

If pip3 isn’t working, you can try:

sudo apt install python3-mysqldb

回答 18

我的环境是:

  • Windows 10专业版,
  • Python 3.7(python-3.7.1-amd64.exe),
  • MySQL 8.0(mysql-installer-web-community-8.0.13.0.msi)

pip安装mysqlclient-1.3.13-cp37-cp37m-win_amd64.whl

为我工作。

import MySQLdb, sys


# --------------------------------------------------
# Connect to MySQL
# --------------------------------------------------
try:
    db = MySQLdb.connect(host="localhost", user="user", passwd="pass", db="database", charset='cp1251')
except MySQLdb.Error as e:
    print ("Error %d: %s" % (e.args[0], e.args[1]))
    sys.exit()

# Creating cursor 
cursor = db.cursor()

My environment are:

  • Windows 10 Pro,
  • Python 3.7 (python-3.7.1-amd64.exe),
  • MySQL 8.0 (mysql-installer-web-community-8.0.13.0.msi)

pip install mysqlclient-1.3.13-cp37-cp37m-win_amd64.whl

works for me.

import MySQLdb, sys


# --------------------------------------------------
# Connect to MySQL
# --------------------------------------------------
try:
    db = MySQLdb.connect(host="localhost", user="user", passwd="pass", db="database", charset='cp1251')
except MySQLdb.Error as e:
    print ("Error %d: %s" % (e.args[0], e.args[1]))
    sys.exit()

# Creating cursor 
cursor = db.cursor()

回答 19

实际上,按照@Nick T的回答对我不起作用,我尝试apt-get install python-mysqldb为我工作

root@2fb0da64a933:/home/test_scrapy# apt-get install python-mysqldb
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libmariadbclient18 mysql-common
Suggested packages:
  default-mysql-server | virtual-mysql-server python-egenix-mxdatetime python-mysqldb-dbg
The following NEW packages will be installed:
  libmariadbclient18 mysql-common python-mysqldb
0 upgraded, 3 newly installed, 0 to remove and 29 not upgraded.
Need to get 843 kB of archives.
After this operation, 4611 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://deb.debian.org/debian stretch/main amd64 mysql-common all 5.8+1.0.2 [5608 B]
Get:2 http://deb.debian.org/debian stretch/main amd64 libmariadbclient18 amd64 10.1.38-0+deb9u1 [785 kB]
Get:3 http://deb.debian.org/debian stretch/main amd64 python-mysqldb amd64 1.3.7-1.1 [52.1 kB]                    
Fetched 843 kB in 23s (35.8 kB/s)                                                                                 
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package mysql-common.
(Reading database ... 13223 files and directories currently installed.)
Preparing to unpack .../mysql-common_5.8+1.0.2_all.deb ...
Unpacking mysql-common (5.8+1.0.2) ...
Selecting previously unselected package libmariadbclient18:amd64.
Preparing to unpack .../libmariadbclient18_10.1.38-0+deb9u1_amd64.deb ...
Unpacking libmariadbclient18:amd64 (10.1.38-0+deb9u1) ...
Selecting previously unselected package python-mysqldb.
Preparing to unpack .../python-mysqldb_1.3.7-1.1_amd64.deb ...
Unpacking python-mysqldb (1.3.7-1.1) ...
Setting up mysql-common (5.8+1.0.2) ...
update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up libmariadbclient18:amd64 (10.1.38-0+deb9u1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
Setting up python-mysqldb (1.3.7-1.1) ...
root@2fb0da64a933:/home/test_scrapy# python 
Python 2.7.13 (default, Nov 24 2017, 17:33:09) 
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
>>> 

actually, follow @Nick T’s answer doesn’t work for me, i try apt-get install python-mysqldb work for me

root@2fb0da64a933:/home/test_scrapy# apt-get install python-mysqldb
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libmariadbclient18 mysql-common
Suggested packages:
  default-mysql-server | virtual-mysql-server python-egenix-mxdatetime python-mysqldb-dbg
The following NEW packages will be installed:
  libmariadbclient18 mysql-common python-mysqldb
0 upgraded, 3 newly installed, 0 to remove and 29 not upgraded.
Need to get 843 kB of archives.
After this operation, 4611 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://deb.debian.org/debian stretch/main amd64 mysql-common all 5.8+1.0.2 [5608 B]
Get:2 http://deb.debian.org/debian stretch/main amd64 libmariadbclient18 amd64 10.1.38-0+deb9u1 [785 kB]
Get:3 http://deb.debian.org/debian stretch/main amd64 python-mysqldb amd64 1.3.7-1.1 [52.1 kB]                    
Fetched 843 kB in 23s (35.8 kB/s)                                                                                 
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package mysql-common.
(Reading database ... 13223 files and directories currently installed.)
Preparing to unpack .../mysql-common_5.8+1.0.2_all.deb ...
Unpacking mysql-common (5.8+1.0.2) ...
Selecting previously unselected package libmariadbclient18:amd64.
Preparing to unpack .../libmariadbclient18_10.1.38-0+deb9u1_amd64.deb ...
Unpacking libmariadbclient18:amd64 (10.1.38-0+deb9u1) ...
Selecting previously unselected package python-mysqldb.
Preparing to unpack .../python-mysqldb_1.3.7-1.1_amd64.deb ...
Unpacking python-mysqldb (1.3.7-1.1) ...
Setting up mysql-common (5.8+1.0.2) ...
update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up libmariadbclient18:amd64 (10.1.38-0+deb9u1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
Setting up python-mysqldb (1.3.7-1.1) ...
root@2fb0da64a933:/home/test_scrapy# python 
Python 2.7.13 (default, Nov 24 2017, 17:33:09) 
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
>>> 

如何在Python中将字符转换为整数,反之亦然?

问题:如何在Python中将字符转换为整数,反之亦然?

我想要获得一个角色的ASCII价值。

例如,对于角色a,我要获取97,反之亦然。

I want to get, given a character, its ASCII value.

For example, for the character a, I want to get 97, and vice versa.


回答 0

使用chr()ord()

>>> chr(97)
'a'
>>> ord('a')
97

Use chr() and ord():

>>> chr(97)
'a'
>>> ord('a')
97

回答 1

>>> ord('a')
97
>>> chr(97)
'a'
>>> ord('a')
97
>>> chr(97)
'a'

回答 2

ord和chr


如何从Sublime Text 2运行Python代码?

问题:如何从Sublime Text 2运行Python代码?

我想在Sublime Text 2中设置完整的Python IDE。

我想知道如何从编辑器中运行Python代码。使用构建系统完成吗?我该怎么做 ?

I want to set up a complete Python IDE in Sublime Text 2.

I want to know how to run the Python code from within the editor. Is it done using build system? How do I do it ?


回答 0

工具->构建系统->(选择)Python然后:

跑步:

      Tools -> Build

      -or-

      Ctrl + B

      CMD + B  (OSX)

这将在控制台中启动您的文件,该控制台应位于编辑器的底部。

停止:

       Ctrl + Break or Tools -> Cancel Build

       Fn + C (OSX)

您可以在Break此处找到密钥的位置:http : //en.wikipedia.org/wiki/Break_key

注意:CTRL + C工作。

Ctrl + Break不起作用时该怎么办:

去:

首选项->键绑定-用户

并粘贴以下行:

{"keys": ["ctrl+shift+c"], "command": "exec", "args": {"kill": true} } 

现在,您可以使用ctrl+shift+c代替CTRL+BREAK

Tools -> Build System -> (choose) Python then:

To Run:

      Tools -> Build

      -or-

      Ctrl + B

      CMD + B  (OSX)

This would start your file in the console which should be at the bottom of the editor.

To Stop:

       Ctrl + Break or Tools -> Cancel Build

       Fn + C (OSX)

You can find out where your Break key is here: http://en.wikipedia.org/wiki/Break_key.

Note: CTRL + C will NOT work.

What to do when Ctrl + Break does not work:

Go to:

Preferences -> Key Bindings – User

and paste the line below:

{"keys": ["ctrl+shift+c"], "command": "exec", "args": {"kill": true} } 

Now, you can use ctrl+shift+c instead of CTRL+BREAK


回答 1

在Mac OS X上,以.py扩展名保存文件。按+ B。它在下面的窗口中运行。

在此处输入图片说明

On Mac OS X, save your file with a .py extension. Press + B. It runs in a window below.

enter image description here


回答 2

编辑%APPDATA%\ Sublime Text 2 \ Python \ Python.sublime-build

将内容更改为:

{
    "cmd": ["C:\\python27\\python.exe", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

将“ c:\ python27”部分更改为系统中具有的任何版本的python。

Edit %APPDATA%\Sublime Text 2\Python\Python.sublime-build

Change content to:

{
    "cmd": ["C:\\python27\\python.exe", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

change the “c:\python27” part to any version of python you have in your system.


回答 3

要运行CtrlB(通过回答matiit

但是当CtrlB 不起作用时,Sublime Text可能找不到Python解释器。尝试运行程序时,请参阅日志并在路径中找到对Python的引用。

[cmd:  [u'python', u'-u', u'C:\\scripts\\test.py']]
[path: ...;C:\Python27 32bit;...]

关键是它试图通过命令行运行python,cmd如下所示:

python -u C:\scripts\test.py

如果您无法从cmd运行python,那么Sublime Text也不会。
(在cmd中自己尝试,在其中键入python并运行它,应该显示python命令行)

您可以更改Sublime Text构建公式或System %PATH%

  • 要设置您的%PATH%
    * 您将需要重新启动编辑器以加载新的%PATH%

    • 运行命令行*,然后输入以下命令:*需要以管理员
      SETX /M PATH "%PATH%;<python_folder>"
      身份运行,例如:SETX /M PATH "%PATH%;C:\Python27;C:\Python27\Scripts"

    • 手动:(最好)在字符串末尾
      添加;C:\Python27;C:\Python27\Scripts在Win7中设置路径

  • 要设置解释器的路径而不弄乱系统,%PATH%请参阅ppy的答案。

To RUN press CtrlB (answer by matiit)

But when CtrlB does not work, Sublime Text probably can’t find the Python Interpreter. When trying to run your program, see the log and find the reference to Python in path.

[cmd:  [u'python', u'-u', u'C:\\scripts\\test.py']]
[path: ...;C:\Python27 32bit;...]

The point is that it tries to run python via command line, the cmd looks like:

python -u C:\scripts\test.py

If you can’t run python from cmd, Sublime Text can’t too.
(Try it yourself in cmd, type python in it and run it, python commandline should appear)

SOLUTION

You can either change the Sublime Text build formula or the System %PATH%.

  • To set your %PATH%:
    *You will need to restart your editor to load new %PATH%

    • Run Command Line* and enter this command: *needs to be run as administrator
      SETX /M PATH "%PATH%;<python_folder>"
      for example: SETX /M PATH "%PATH%;C:\Python27;C:\Python27\Scripts"

    • OR manually: (preferable)
      Add ;C:\Python27;C:\Python27\Scripts at the end of the string. Setting Path in Win7

  • To set the interpreter’s path without messing with System %PATH% see this answer by ppy.


回答 4

您可以使用SublimeREPL(首先需要安装Package Control)。

You can use SublimeREPL (you need to have Package Control installed first).


回答 5

如果使用python 3.x,则需要编辑 Python3.sublime-build

(首选项>浏览包> Python 3)

看起来像这样:

{
  "path": "/usr/local/bin",
  "cmd": ["python3", "-u", "$file"],
  "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
  "selector": "source.python"
}

If using python 3.x you need to edit the Python3.sublime-build

(Preferences > Browse packages > Python 3)

to look like this:

{
  "path": "/usr/local/bin",
  "cmd": ["python3", "-u", "$file"],
  "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
  "selector": "source.python"
}

回答 6

[这适用于ST3(Win),不确定ST2]

要使输出在Sublime中作为另一个文件可见(为错误显示一个文件),请执行以下操作:

  1. 创建一个新的构建系统: Tools > Build Systems > New Build System...
  2. 使用以下配置:
    {
        “ cmd”:[“ python.exe”,“ $ file”,“ 1>”,“ $ file_name .__ STDOUT __。txt”,“ 2>”,“ $ file_name .__ STDERR __。txt”],
        “ selector”:“ source.python”,
        “外壳”:是的,
        “ working_dir”:“ $ file_dir”
    }
  1. 对于您的Python文件,选择上面的构建系统配置文件: Tools > Build Systems > {your_new_build_system_filename}
  2. ctrl + b
  3. 现在,在文件旁边,例如,"file.py"您将拥有"file.__STDOUT__.py""file.__STDERR__.py"(对于错误,如果有的话)
  4. 如果将窗口分为三列或一个网格,您将立即看到结果,而无需切换面板/窗口

[ This applies to ST3 (Win), not sure about ST2 ]

To have the output visible in Sublime as another file (+ one for errors), do this:

  1. Create a new build system: Tools > Build Systems > New Build System...
  2. Use the following configuration:

    {
        "cmd": ["python.exe", "$file", "1>", "$file_name.__STDOUT__.txt", "2>", "$file_name.__STDERR__.txt"],
        "selector": "source.python",
        "shell": true,
        "working_dir": "$file_dir"
    }
  1. For your Python file select the above build system configuration file: Tools > Build Systems > {your_new_build_system_filename}
  2. ctrl + b
  3. Now, next to your file, e.g. "file.py" you’ll have "file.__STDOUT__.py" and "file.__STDERR__.py" (for errors, if any)
  4. If you split your window into 3 columns, or a grid, you’ll see the result immediately, without a need to switch panels / windows

回答 7

酷你们,我刚发现这个:

http://ptomato.wordpress.com/2012/02/09/geek-tip-running-python-guis-in-sublime-text-2/

它解释了(像上面的答案之一一样)如何在默认目录中编辑此exec.py。

我的问题是我的PYTHON UI APPLICATION无法启动。我从以下片段中注释掉了最后一行:

    # Hide the console window on Windows
    startupinfo = None
    if os.name == "nt":
        startupinfo = subprocess.STARTUPINFO()
        #startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

而且,taaadaaaa,我可以通过按Ctrl + B来启动我的应用。有趣的话,嗯?非常感谢您写这篇文章的人;-)

Cool U guys, I just found this:

http://ptomato.wordpress.com/2012/02/09/geek-tip-running-python-guis-in-sublime-text-2/

It explains (like one of the answers above) how to edit this exec.py in the default directory.

I had the problem that my PYTHON UI APPLICATION would not start. I commented out the last line from the following snipped:

    # Hide the console window on Windows
    startupinfo = None
    if os.name == "nt":
        startupinfo = subprocess.STARTUPINFO()
        #startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

and, taaadaaaa, I could start my app by pressing Ctrl+B. Funny line anyways, uh? And a big thank you to whoever wrote that article ;-)


回答 8

您可以通过“查看/显示控制台”或Ctrl+ 访问Python控制台`

You can access the Python console via “View/Show console” or Ctrl+`.


回答 9

我解决了这个问题:

> Preferences –> Browse Packages –> Default 

打开第exec.py41-42行附近的文件,代码应如下所示:

for k, v in proc_env.iteritems():
    proc_env[k] = os.path.expandvars(v).encode(sys.getfilesystemencoding())

然后将其删除或编辑为:

try:    
    for k, v in proc_env.iteritems():
        proc_env[k] = os.path.expandvars(v).encode(sys.getfilesystemencoding())
except:
    print 'foobar'

I solved this problem :

> Preferences –> Browse Packages –> Default 

Open the exec.py file, near line 41-42, the code should look like this :

for k, v in proc_env.iteritems():
    proc_env[k] = os.path.expandvars(v).encode(sys.getfilesystemencoding())

then delete it or edit it as :

try:    
    for k, v in proc_env.iteritems():
        proc_env[k] = os.path.expandvars(v).encode(sys.getfilesystemencoding())
except:
    print 'foobar'

回答 10

我今天遇到了同样的问题。这是我设法在Sublime Text 3中运行python代码的方式:

  1. Ctrl+ B(对于Mac,+ B)开始构建系统。它应该立即执行文件。
  2. 遵循此答案以了解如何自定义构建系统。

接下来,您需要将内容替换Python.sublime-build

{
    "cmd": ["/usr/local/bin/python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",
}

您当然可以进一步自定义它以适合您的需求。

I ran into the same problem today. And here is how I managed to run python code in Sublime Text 3:

  1. Press Ctrl + B (for Mac, + B) to start build system. It should execute the file now.
  2. Follow this answer to understand how to customise build system.

What you need to do next is replace the content in Python.sublime-build to

{
    "cmd": ["/usr/local/bin/python", "-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python",
}

You can of course further customise it to something that works for you.


回答 11

在python v3.x中,您应该转到:Tools->Build System->New Build System

然后,在sublime文本编辑器中弹出untitled.sublime-build窗口,输入设置为:

{

    "cmd": ["path_to_the_python.exe","-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

要查看路径,请执行以下操作Type following in terminal as

python
>>> import sys
>>>print(sys.executable)

您可以制作多个构建系统,但默认情况下,应将其保存在具有.sublime-build扩展名的Sublime文本包中

然后,选择新的构建系统 ,然后cltr+b根据您的操作系统按或其他。

In python v3.x you should go to : Tools->Build System->New Build System.

Then, it pop up the untitled.sublime-build window in sublime text editor.Enter setting as:

{

    "cmd": ["path_to_the_python.exe","-u", "$file"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}

To see the path, Type following in terminal as:

python
>>> import sys
>>>print(sys.executable)

You can make more than one Build System but it should default save inside Packages of Sublime text with .sublime-build extension.

Then, select the new Build System and press cltr+b or other based on your os.


回答 12

我有同样的问题。您可能尚未保存文件。确保使用.py扩展名保存您的代码,并且该代码应该可以工作。

I had the same problem. You probably haven’t saved the file yet. Make sure to save your code with .py extension and it should work.


回答 13

关于上述构建系统要注意的一件事:您可以编写(并使用)自定义.sublime-build文件,甚至可以编写每个项目build_systems子句(在项目设置中)。这使您可以做一些有用的事情,例如使用ANSI颜色输出的精美测试运行程序

要获得更多的“完整IDE”功能,可以使用出色的SublimePythonIDE软件包:

  • 代码完成(英特尔)
  • 跳转到定义和对象描述
  • 适当的棉绒/ pep8
  • 用virtualenv支持不同的解释器

披露:我已经贡献了PR该程序包,我用它所有的时间,但 其他人

One thing to note about the aforementioned build system: you can write (and use) custom .sublime-build files or even per project build_systems clause (in your project settings). This allows you to do useful things like a fancy test runner with ANSI colors output.

For even more “full IDE” features, you can use the excellent SublimePythonIDE package:

  • code completion (intel)
  • jump to definition & object description
  • proper linting/pep8
  • supports different interpreters with virtualenv

Disclosure: I’ve contributed a PR to that package, and I use it all the time, but there are others.


回答 14

在Sublime旁边使用真正的python控制台

Sublime的构建系统和SublimeREPL(上面的答案)都受到限制,因为您在运行文件后无法轻松地与工作空间变量进行交互。

如果要运行脚本,然后以类似于REPL的方式工作(就像在IDE中一样),则建议将Sublime与IPython控制台一起打开。您可以使用AutoHotKey(Windows)或AutoKey(Linux)进行设置,以使单个快捷方式将复制文件名(或仅复制所选的代码),然后将其粘贴到控制台中以运行文件。

LinuxWindows的详细说明

Use a real python console alongside Sublime

Both Sublime’s build system and SublimeREPL (the answers above) are limited in that you can’t easily interact with the workspace variables after you run your file.

If you want to run a script, then work in a REPL-like fashion (like you would in an IDE), then I recommend having Sublime open alongside an IPython console. Using AutoHotKey (Windows) or AutoKey (Linux), you can set this up such that a single shortcut will copy the filename (or just the selected code) and then paste this in the console to run the file.

Detailed instructions for Linux or Windows


第一次出现时分裂

问题:第一次出现时分裂

在首次出现定界符时分割字符串的最佳方法是什么?

例如:

"123mango abcd mango kiwi peach"

首先分裂mango得到:

"abcd mango kiwi peach"

What would be the best way to split a string on the first occurrence of a delimiter?

For example:

"123mango abcd mango kiwi peach"

splitting on the first mango to get:

"abcd mango kiwi peach"

回答 0

文档

str.split([sep[, maxsplit]])

使用sep作为分隔符字符串,返回字符串中单词的列表。如果给出了maxsplit,则最多完成maxsplit分割(因此,列表中最多maxsplit+1包含元素)。

s.split('mango', 1)[1]

From the docs:

str.split([sep[, maxsplit]])

Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements).

s.split('mango', 1)[1]

回答 1

>>> s = "123mango abcd mango kiwi peach"
>>> s.split("mango", 1)
['123', ' abcd mango kiwi peach']
>>> s.split("mango", 1)[1]
' abcd mango kiwi peach'
>>> s = "123mango abcd mango kiwi peach"
>>> s.split("mango", 1)
['123', ' abcd mango kiwi peach']
>>> s.split("mango", 1)[1]
' abcd mango kiwi peach'

回答 2

对我来说,更好的方法是:

s.split('mango', 1)[-1]

…因为如果发生这种情况不在字符串中,您将得到“ IndexError: list index out of range"

因此-1不会造成任何伤害的原因发生次数已经设置为1。

For me the better approach is that:

s.split('mango', 1)[-1]

…because if happens that occurrence is not in the string you’ll get “IndexError: list index out of range".

Therefore -1 will not get any harm cause number of occurrences is already set to one.


回答 3

您也可以使用str.partition

>>> text = "123mango abcd mango kiwi peach"

>>> text.partition("mango")
('123', 'mango', ' abcd mango kiwi peach')

>>> text.partition("mango")[-1]
' abcd mango kiwi peach'

>>> text.partition("mango")[-1].lstrip()  # if whitespace strip-ing is needed
'abcd mango kiwi peach'

使用的优点str.partition是它总是会返回以下形式的元组:

(<pre>, <separator>, <post>)

因此,这使得解压缩输出变得非常灵活,因为在结果元组中总会有3个元素。

You can also use str.partition:

>>> text = "123mango abcd mango kiwi peach"

>>> text.partition("mango")
('123', 'mango', ' abcd mango kiwi peach')

>>> text.partition("mango")[-1]
' abcd mango kiwi peach'

>>> text.partition("mango")[-1].lstrip()  # if whitespace strip-ing is needed
'abcd mango kiwi peach'

The advantage of using str.partition is that it’s always gonna return a tuple in the form:

(<pre>, <separator>, <post>)

So this makes unpacking the output really flexible as there’s always going to be 3 elements in the resulting tuple.


回答 4

df.columnname[1].split('.', 1)

这将以第一个出现的“。”分割数据。在字符串或数据框列中的值。

df.columnname[1].split('.', 1)

This will split data with the first occurrence of ‘.’ in the string or data frame column value.


在代码中安装python模块

问题:在代码中安装python模块

我需要直接在脚本中从PyPi安装软件包。也许有一些模块或distutilsdistributepip等)功能使我可以执行类似的操作,pypi.install('requests')并且请求将被安装到我的virtualenv中。

I need to install a package from PyPi straight within my script. Maybe there’s some module or distutils (distribute, pip etc.) feature which allows me to just execute something like pypi.install('requests') and requests will be installed into my virtualenv.


回答 0

从脚本安装软件包的官方推荐方法是通过子进程调用pip的命令行界面。pip不支持此处提出的大多数其他答案。此外,自pip v10起,所有代码都已pip._internal精确定位,以使用户清楚不允许以编程方式使用pip。

使用sys.executable,以确保您将调用相同pip与当前运行相关联。

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

The officially recommended way to install packages from a script is by calling pip’s command-line interface via a subprocess. Most other answers presented here are not supported by pip. Furthermore since pip v10, all code has been moved to pip._internal precisely in order to make it clear to users that programmatic use of pip is not allowed.

Use sys.executable to ensure that you will call the same pip associated with the current runtime.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

回答 1

您还可以使用类似:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')

You can also use something like:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')

回答 2

如果要用于pip安装所需的软件包并在安装后将其导入,则可以使用以下代码:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

如果您以用户身份安装软件包,则可能会遇到不能仅导入软件包的问题。请参阅如何刷新sys.path?有关其他信息。

If you want to use pip to install required package and import it after installation, you can use this code:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

If you installed a package as a user you can encounter the problem that you cannot just import the package. See How to refresh sys.path? for additional information.


回答 3

这应该工作:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])

This should work:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])

回答 4

我在@Aaron的答案中添加了一些异常处理。

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd

i added some exception handling to @Aaron’s answer.

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd

回答 5

您可以使用“ install_requires”选项在自己程序包的setup.py中定义从属模块。

如果您的软件包需要生成一些控制台脚本,则可以使用“ console_scripts”入口点来生成包装脚本,该脚本将被放置在“ bin”文件夹(例如您的virtualenv环境)中。

You define the dependent module inside the setup.py of your own package with the “install_requires” option.

If your package needs to have some console script generated then you can use the “console_scripts” entry point in order to generate a wrapper script that will be placed within the ‘bin’ folder (e.g. of your virtualenv environment).


如何创建对象并为其添加属性?

问题:如何创建对象并为其添加属性?

我想在Python中创建一个动态对象(在另一个对象内部),然后向其添加属性。

我试过了:

obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')

但这没用。

有任何想法吗?

编辑:

我正在从for循环遍历值列表的循环中设置属性,例如

params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()

for p in params:
   obj.a.p # where p comes from for loop variable

在上面的例子中,我会得到obj.a.attr1obj.a.attr2obj.a.attr3

我使用该setattr函数是因为我不知道如何obj.a.NAMEfor循环中进行操作。

如何根据上例中的值设置属性p

I want to create a dynamic object (inside another object) in Python and then add attributes to it.

I tried:

obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')

but this didn’t work.

Any ideas?

edit:

I am setting the attributes from a for loop which loops through a list of values, e.g.

params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()

for p in params:
   obj.a.p # where p comes from for loop variable

In the above example I would get obj.a.attr1, obj.a.attr2, obj.a.attr3.

I used the setattr function because I didn’t know how to do obj.a.NAME from a for loop.

How would I set the attribute based on the value of p in the example above?


回答 0

您可以使用我的古老的Bunch配方,但是如果您不想创建“绑定类”,那么Python中已经存在一个非常简单的类-所有函数都可以具有任意属性(包括lambda函数)。因此,以下工作:

obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')

与古老的Bunch食谱相比,清晰度是否还可以,这是一个样式决定,我当然会留给您。

You could use my ancient Bunch recipe, but if you don’t want to make a “bunch class”, a very simple one already exists in Python — all functions can have arbitrary attributes (including lambda functions). So, the following works:

obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')

Whether the loss of clarity compared to the venerable Bunch recipe is OK, is a style decision I will of course leave up to you.


回答 1

内置object实例可以实例化,但是不能设置任何属性。(为此,我希望可以。)它没有一个__dict__用于保存属性的属性。

我通常只是这样做:

class Object(object):
    pass

a = Object()
a.somefield = somevalue

如果可以的话,Object根据我要输入的数据类型,给该类一个更有意义的名称。

某些人做不同的事情,他们使用的子类dict允许属性访问获得关键。(d.key代替d['key']

编辑:对于您的问题的补充,使用setattr就可以了。您只是不能setattrobject()实例上使用。

params = ['attr1', 'attr2', 'attr3']
for p in params:
    setattr(obj.a, p, value)

The built-in object can be instantiated but can’t have any attributes set on it. (I wish it could, for this exact purpose.) It doesn’t have a __dict__ to hold the attributes.

I generally just do this:

class Object(object):
    pass

a = Object()
a.somefield = somevalue

When I can, I give the Object class a more meaningful name, depending on what kind of data I’m putting in it.

Some people do a different thing, where they use a sub-class of dict that allows attribute access to get at the keys. (d.key instead of d['key'])

Edit: For the addition to your question, using setattr is fine. You just can’t use setattr on object() instances.

params = ['attr1', 'attr2', 'attr3']
for p in params:
    setattr(obj.a, p, value)

回答 2

types.SimpleNamespacePython 3.3+中有一个

obj = someobject
obj.a = SimpleNamespace()
for p in params:
    setattr(obj.a, p, value)
# obj.a.attr1

collections.namedtupletyping.NamedTuple可用于不可变的对象。PEP 557-数据类 建议了一种可变的替代方法。

要获得更丰富的功能,可以尝试使用attrspackage。请参阅用法示例

There is types.SimpleNamespace class in Python 3.3+:

obj = someobject
obj.a = SimpleNamespace()
for p in params:
    setattr(obj.a, p, value)
# obj.a.attr1

collections.namedtuple, typing.NamedTuple could be used for immutable objects. PEP 557 — Data Classes suggests a mutable alternative.

For a richer functionality, you could try attrs package. See an example usage.


回答 3

有几种方法可以实现此目标。基本上,您需要一个可扩展的对象。

obj.a = type('Test', (object,), {})  
obj.a.b = 'fun'  

obj.b = lambda:None

class Test:
  pass
obj.c = Test()

There are a few ways to reach this goal. Basically you need an object which is extendable.

obj.a = type('Test', (object,), {})  
obj.a.b = 'fun'  

obj.b = lambda:None

class Test:
  pass
obj.c = Test()

回答 4

mock模块基本上是为此目的而设计的。

import mock
obj = mock.Mock()
obj.a = 5

The mock module is basically made for that.

import mock
obj = mock.Mock()
obj.a = 5

回答 5

现在,您可以执行操作(不确定答案是否与罪恶相同):

MyObject = type('MyObject', (object,), {})
obj = MyObject()
obj.value = 42

Now you can do (not sure if it’s the same answer as evilpie):

MyObject = type('MyObject', (object,), {})
obj = MyObject()
obj.value = 42

回答 6

请尝试以下代码:

$ python
>>> class Container(object):
...     pass 
...
>>> x = Container()
>>> x.a = 10
>>> x.b = 20
>>> x.banana = 100
>>> x.a, x.b, x.banana
(10, 20, 100)
>>> dir(x)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',     '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'banana']

Try the code below:

$ python
>>> class Container(object):
...     pass 
...
>>> x = Container()
>>> x.a = 10
>>> x.b = 20
>>> x.banana = 100
>>> x.a, x.b, x.banana
(10, 20, 100)
>>> dir(x)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',     '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'banana']

回答 7

您也可以直接使用类对象。它创建一个命名空间:

class a: pass
a.somefield1 = 'somevalue1'
setattr(a, 'somefield2', 'somevalue2')

You can also use a class object directly; it creates a namespace:

class a: pass
a.somefield1 = 'somevalue1'
setattr(a, 'somefield2', 'somevalue2')

回答 8

正如文档所说

object__dict__,所以你不能指定任意属性的实例object类。

您可以只使用伪类实例。

as docs say:

Note: object does not have a __dict__, so you can’t assign arbitrary attributes to an instance of the object class.

You could just use dummy-class instance.


回答 9

这些解决方案在测试期间非常有帮助。基于其他人的答案,我在Python 2.7.9中执行此操作(没有静态方法,我得到TypeError(未绑定方法…):

In [11]: auth = type('', (), {})
In [12]: auth.func = staticmethod(lambda i: i * 2)
In [13]: auth.func(2)
Out[13]: 4

These solutions are very helpful during testing. Building on everyone else’s answers I do this in Python 2.7.9 (without staticmethod I get a TypeError (unbound method…):

In [11]: auth = type('', (), {})
In [12]: auth.func = staticmethod(lambda i: i * 2)
In [13]: auth.func(2)
Out[13]: 4

回答 10

您正在使用哪些对象?只是尝试了一个示例类,它运行良好:

class MyClass:
  i = 123456
  def f(self):
    return "hello world"

b = MyClass()
b.c = MyClass()
setattr(b.c, 'test', 123)
b.c.test

我得到123了答案。

我看到此失败的唯一情况是,如果您正在尝试setattr对内置对象进行操作。

更新:从注释中可以看出是重复的:为什么不能在python中向对象添加属性?

Which objects are you using? Just tried that with a sample class and it worked fine:

class MyClass:
  i = 123456
  def f(self):
    return "hello world"

b = MyClass()
b.c = MyClass()
setattr(b.c, 'test', 123)
b.c.test

And I got 123 as the answer.

The only situation where I see this failing is if you’re trying a setattr on a builtin object.

Update: From the comment this is a repetition of: Why can’t you add attributes to object in python?


回答 11

到今天晚了,这是我的一分钱,它的对象恰好在应用程序中保留了一些有用的路径,但是您可以将其适应于任何您希望通过getattr和点表示法访问信息的命令(这是我认为这个问题的真正含义):

import os

def x_path(path_name):
    return getattr(x_path, path_name)

x_path.root = '/home/x'
for name in ['repository', 'caches', 'projects']:
    setattr(x_path, name, os.path.join(x_path.root, name))

这很酷,因为现在:

In [1]: x_path.projects
Out[1]: '/home/x/projects'

In [2]: x_path('caches')
Out[2]: '/home/x/caches'

因此,它像上面的答案一样使用函数对象,但使用函数来获取值(您仍然可以使用,(getattr, x_path, 'repository')而不是x_path('repository')愿意使用)。

Coming to this late in the day but here is my pennyworth with an object that just happens to hold some useful paths in an app but you can adapt it for anything where you want a sorta dict of information that you can access with getattr and dot notation (which is what I think this question is really about):

import os

def x_path(path_name):
    return getattr(x_path, path_name)

x_path.root = '/home/x'
for name in ['repository', 'caches', 'projects']:
    setattr(x_path, name, os.path.join(x_path.root, name))

This is cool because now:

In [1]: x_path.projects
Out[1]: '/home/x/projects'

In [2]: x_path('caches')
Out[2]: '/home/x/caches'

So this uses the function object like the above answers but uses the function to get the values (you can still use (getattr, x_path, 'repository') rather than x_path('repository') if you prefer).


回答 12

如果在创建嵌套对象之前可以确定所有属性和值并将它们聚合在一起,那么我们可以创建一个新类,该类在创建时采用字典参数。

# python 2.7

class NestedObject():
    def __init__(self, initial_attrs):
        for key in initial_attrs:
            setattr(self, key, initial_attrs[key])

obj = someobject
attributes = { 'attr1': 'val1', 'attr2': 'val2', 'attr3': 'val3' }
obj.a = NestedObject(attributes)
>>> obj.a.attr1
'val1'
>>> obj.a.attr2
'val2'
>>> obj.a.attr3
'val3'

我们还可以允许关键字参数。看到这篇文章

class NestedObject(object):
    def __init__(self, *initial_attrs, **kwargs):
        for dictionary in initial_attrs:
            for key in dictionary:
                setattr(self, key, dictionary[key])
        for key in kwargs:
            setattr(self, key, kwargs[key])


obj.a = NestedObject(attr1='val1', attr2='val2', attr3= 'val3')

If we can determine and aggregate all the attributes and values together before creating the nested object, then we could create a new class that takes a dictionary argument on creation.

# python 2.7

class NestedObject():
    def __init__(self, initial_attrs):
        for key in initial_attrs:
            setattr(self, key, initial_attrs[key])

obj = someobject
attributes = { 'attr1': 'val1', 'attr2': 'val2', 'attr3': 'val3' }
obj.a = NestedObject(attributes)
>>> obj.a.attr1
'val1'
>>> obj.a.attr2
'val2'
>>> obj.a.attr3
'val3'

We can also allow keyword arguments. See this post.

class NestedObject(object):
    def __init__(self, *initial_attrs, **kwargs):
        for dictionary in initial_attrs:
            for key in dictionary:
                setattr(self, key, dictionary[key])
        for key in kwargs:
            setattr(self, key, kwargs[key])


obj.a = NestedObject(attr1='val1', attr2='val2', attr3= 'val3')

回答 13

di = {}
for x in range(20):
    name = '_id%s' % x
    di[name] = type(name, (object), {})
    setattr(di[name], "attr", "value")
di = {}
for x in range(20):
    name = '_id%s' % x
    di[name] = type(name, (object), {})
    setattr(di[name], "attr", "value")

回答 14

我看到的其他方式是这样的:

import maya.cmds

def getData(objets=None, attrs=None):
    di = {}
    for obj in objets:
        name = str(obj)
        di[name]=[]
        for at in attrs:
            di[name].append(cmds.getAttr(name+'.'+at)[0])
    return di

acns=cmds.ls('L_vest_*_',type='aimConstraint')
attrs=['offset','aimVector','upVector','worldUpVector']

getData(acns,attrs)

Other way i see, this way:

import maya.cmds

def getData(objets=None, attrs=None):
    di = {}
    for obj in objets:
        name = str(obj)
        di[name]=[]
        for at in attrs:
            di[name].append(cmds.getAttr(name+'.'+at)[0])
    return di

acns=cmds.ls('L_vest_*_',type='aimConstraint')
attrs=['offset','aimVector','upVector','worldUpVector']

getData(acns,attrs)

在Python中打印多个参数

问题:在Python中打印多个参数

这只是我的代码的一部分:

print("Total score for %s is %s  ", name, score)

但我希望它打印出来:

“(姓名)的总分是(分数)”

其中name是列表中的变量,score是整数。如果有帮助的话,这就是Python 3.3。

This is just a snippet of my code:

print("Total score for %s is %s  ", name, score)

But I want it to print out:

“Total score for (name) is (score)”

where name is a variable in a list and score is an integer. This is Python 3.3 if that helps at all.


回答 0

有很多方法可以做到这一点。要使用%-formatting 修复当前代码,您需要传入一个元组:

  1. 将其作为元组传递:

    print("Total score for %s is %s" % (name, score))

具有单个元素的元组看起来像('this',)

这是其他一些常见的实现方法:

  1. 将其作为字典传递:

    print("Total score for %(n)s is %(s)s" % {'n': name, 's': score})

还有一种新型的字符串格式,可能更容易阅读:

  1. 使用新型的字符串格式:

    print("Total score for {} is {}".format(name, score))
  2. 使用带有数字的新型字符串格式(可用于重新排序或多次打印相同的字符):

    print("Total score for {0} is {1}".format(name, score))
  3. 使用具有显式名称的新型字符串格式:

    print("Total score for {n} is {s}".format(n=name, s=score))
  4. 连接字符串:

    print("Total score for " + str(name) + " is " + str(score))

我认为最清楚的两个是:

  1. 只需将值作为参数传递:

    print("Total score for", name, "is", score)

    如果您不希望print在上面的示例中自动插入空格,请更改sep参数:

    print("Total score for ", name, " is ", score, sep='')

    如果您使用的是Python 2,将不能使用最后两个,因为print这不是Python 2中的函数。不过,您可以从__future__以下方式导入此行为:

    from __future__ import print_function
  2. f在Python 3.6中使用新的-string格式:

    print(f'Total score for {name} is {score}')

There are many ways to do this. To fix your current code using %-formatting, you need to pass in a tuple:

  1. Pass it as a tuple:

    print("Total score for %s is %s" % (name, score))
    

A tuple with a single element looks like ('this',).

Here are some other common ways of doing it:

  1. Pass it as a dictionary:

    print("Total score for %(n)s is %(s)s" % {'n': name, 's': score})
    

There’s also new-style string formatting, which might be a little easier to read:

  1. Use new-style string formatting:

    print("Total score for {} is {}".format(name, score))
    
  2. Use new-style string formatting with numbers (useful for reordering or printing the same one multiple times):

    print("Total score for {0} is {1}".format(name, score))
    
  3. Use new-style string formatting with explicit names:

    print("Total score for {n} is {s}".format(n=name, s=score))
    
  4. Concatenate strings:

    print("Total score for " + str(name) + " is " + str(score))
    

The clearest two, in my opinion:

  1. Just pass the values as parameters:

    print("Total score for", name, "is", score)
    

    If you don’t want spaces to be inserted automatically by print in the above example, change the sep parameter:

    print("Total score for ", name, " is ", score, sep='')
    

    If you’re using Python 2, won’t be able to use the last two because print isn’t a function in Python 2. You can, however, import this behavior from __future__:

    from __future__ import print_function
    
  2. Use the new f-string formatting in Python 3.6:

    print(f'Total score for {name} is {score}')
    

回答 1

有很多打印方法。

让我们看另一个例子。

a = 10
b = 20
c = a + b

#Normal string concatenation
print("sum of", a , "and" , b , "is" , c) 

#convert variable into str
print("sum of " + str(a) + " and " + str(b) + " is " + str(c)) 

# if you want to print in tuple way
print("Sum of %s and %s is %s: " %(a,b,c))  

#New style string formatting
print("sum of {} and {} is {}".format(a,b,c)) 

#in case you want to use repr()
print("sum of " + repr(a) + " and " + repr(b) + " is " + repr(c))

EDIT :

#New f-string formatting from Python 3.6:
print(f'Sum of {a} and {b} is {c}')

There are many ways to print that.

Let’s have a look with another example.

a = 10
b = 20
c = a + b

#Normal string concatenation
print("sum of", a , "and" , b , "is" , c) 

#convert variable into str
print("sum of " + str(a) + " and " + str(b) + " is " + str(c)) 

# if you want to print in tuple way
print("Sum of %s and %s is %s: " %(a,b,c))  

#New style string formatting
print("sum of {} and {} is {}".format(a,b,c)) 

#in case you want to use repr()
print("sum of " + repr(a) + " and " + repr(b) + " is " + repr(c))

EDIT :

#New f-string formatting from Python 3.6:
print(f'Sum of {a} and {b} is {c}')

回答 2

使用方法.format()

print("Total score for {0} is {1}".format(name, score))

要么:

// Recommended, more readable code

print("Total score for {n} is {s}".format(n=name, s=score))

要么:

print("Total score for" + name + " is " + score)

要么:

`print("Total score for %s is %d" % (name, score))`

Use: .format():

print("Total score for {0} is {1}".format(name, score))

Or:

// Recommended, more readable code

print("Total score for {n} is {s}".format(n=name, s=score))

Or:

print("Total score for" + name + " is " + score)

Or:

`print("Total score for %s is %d" % (name, score))`

回答 3

在Python 3.6中,f-string它更加干净。

在早期版本中:

print("Total score for %s is %s. " % (name, score))

在Python 3.6中:

print(f'Total score for {name} is {score}.')

会做。

它更高效,更优雅。

In Python 3.6, f-string is much cleaner.

In earlier version:

print("Total score for %s is %s. " % (name, score))

In Python 3.6:

print(f'Total score for {name} is {score}.')

will do.

It is more efficient and elegant.


回答 4

保持简单,我个人喜欢字符串连接:

print("Total score for " + name + " is " + score)

它同时适用于Python 2.7和3.X。

注意:如果score是一个int,则应将其转换为str

print("Total score for " + name + " is " + str(score))

Keeping it simple, I personally like string concatenation:

print("Total score for " + name + " is " + score)

It works with both Python 2.7 an 3.X.

NOTE: If score is an int, then, you should convert it to str:

print("Total score for " + name + " is " + str(score))

回答 5

你试一试:

print("Total score for", name, "is", score)

Just try:

print("Total score for", name, "is", score)

回答 6

只要遵循这个

idiot_type = "the biggest idiot"
year = 22
print("I have been {} for {} years ".format(idiot_type, years))

要么

idiot_type = "the biggest idiot"
year = 22
print("I have been %s for %s years."% (idiot_type, year))

忘记所有其他格式,否则大脑将无法映射所有格式。

Just follow this

idiot_type = "the biggest idiot"
year = 22
print("I have been {} for {} years ".format(idiot_type, years))

OR

idiot_type = "the biggest idiot"
year = 22
print("I have been %s for %s years."% (idiot_type, year))

And forget all others, else the brain won’t be able to map all the formats.


回答 7

print("Total score for %s is %s  " % (name, score))

%s可以替换为%d%f

print("Total score for %s is %s  " % (name, score))

%s can be replace by %d or %f


回答 8

用途f-string

print(f'Total score for {name} is {score}')

要么

用途.format

print("Total score for {} is {}".format(name, score))

Use f-string:

print(f'Total score for {name} is {score}')

Or

Use .format:

print("Total score for {} is {}".format(name, score))

回答 9

如果score是数字,则

print("Total score for %s is %d" % (name, score))

如果score是一个字符串,则

print("Total score for %s is %s" % (name, score))

如果score是数字,%d则为,如果是字符串%s,则为,如果score是浮点型,则为%f

If score is a number, then

print("Total score for %s is %d" % (name, score))

If score is a string, then

print("Total score for %s is %s" % (name, score))

If score is a number, then it’s %d, if it’s a string, then it’s %s, if score is a float, then it’s %f


回答 10

这是我的工作:

print("Total score for " + name + " is " + score)

请记住在for前后放置一个空格is

This is what I do:

print("Total score for " + name + " is " + score)

Remember to put a space after for and before and after is.


张量流的tf.nn.max_pool中的’SAME’和’VALID’填充有什么区别?

问题:张量流的tf.nn.max_pool中的’SAME’和’VALID’填充有什么区别?

什么是“相同”和“有效”填充之间的区别tf.nn.max_pooltensorflow

我认为,“有效”表示在进行最大池化时,边缘外部不会出现零填充。

根据深度学习卷积算法指南,它说池运算符中将没有填充,即仅使用的“ VALID” tensorflow。但是最大池的“相同”填充是tensorflow什么?

What is the difference between ‘SAME’ and ‘VALID’ padding in tf.nn.max_pool of tensorflow?

In my opinion, ‘VALID’ means there will be no zero padding outside the edges when we do max pool.

According to A guide to convolution arithmetic for deep learning, it says that there will be no padding in pool operator, i.e. just use ‘VALID’ of tensorflow. But what is ‘SAME’ padding of max pool in tensorflow?


回答 0

我将举一个例子使其更加清晰:

  • x:输入形状为[2,3],1通道的图像
  • valid_pad:具有2×2内核,步幅2和有效填充的最大池。
  • same_pad:具有2×2内核,步幅2和相同填充的最大池(这是经典的处理方式)

输出形状为:

  • valid_pad:这里,没有填充,因此输出形状为[1,1]
  • same_pad:在这里,我们将图像填充为[2,4]形状(使用-inf,然后应用最大池),因此输出形状为[1、2]

x = tf.constant([[1., 2., 3.],
                 [4., 5., 6.]])

x = tf.reshape(x, [1, 2, 3, 1])  # give a shape accepted by tf.nn.max_pool

valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')

valid_pad.get_shape() == [1, 1, 1, 1]  # valid_pad is [5.]
same_pad.get_shape() == [1, 1, 2, 1]   # same_pad is  [5., 6.]

I’ll give an example to make it clearer:

  • x: input image of shape [2, 3], 1 channel
  • valid_pad: max pool with 2×2 kernel, stride 2 and VALID padding.
  • same_pad: max pool with 2×2 kernel, stride 2 and SAME padding (this is the classic way to go)

The output shapes are:

  • valid_pad: here, no padding so the output shape is [1, 1]
  • same_pad: here, we pad the image to the shape [2, 4] (with -inf and then apply max pool), so the output shape is [1, 2]

x = tf.constant([[1., 2., 3.],
                 [4., 5., 6.]])

x = tf.reshape(x, [1, 2, 3, 1])  # give a shape accepted by tf.nn.max_pool

valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')

valid_pad.get_shape() == [1, 1, 1, 1]  # valid_pad is [5.]
same_pad.get_shape() == [1, 1, 2, 1]   # same_pad is  [5., 6.]


回答 1

如果您喜欢ascii艺术:

  • "VALID" =不带填充:

       inputs:         1  2  3  4  5  6  7  8  9  10 11 (12 13)
                      |________________|                dropped
                                     |_________________|
  • "SAME" =零填充:

                   pad|                                      |pad
       inputs:      0 |1  2  3  4  5  6  7  8  9  10 11 12 13|0  0
                   |________________|
                                  |_________________|
                                                 |________________|

在此示例中:

  • 输入宽度= 13
  • 滤镜宽度= 6
  • 步幅= 5

笔记:

  • "VALID" 只删除最右边的列(或最下面的行)。
  • "SAME" 尝试左右均匀填充,但是如果要添加的列数是奇数,它将在右边添加额外的列,如本示例中的情况(相同的逻辑在垂直方向上适用:可能会有额外的行底部的零)。

编辑

关于名字:

  • 使用"SAME"填充时,如果跨度为1,则图层的输出将具有与其输入相同的空间尺寸。
  • 使用"VALID"填充时,没有“虚构的”填充输入。该图层仅使用有效的输入数据。

If you like ascii art:

  • "VALID" = without padding:

       inputs:         1  2  3  4  5  6  7  8  9  10 11 (12 13)
                      |________________|                dropped
                                     |_________________|
    
  • "SAME" = with zero padding:

                   pad|                                      |pad
       inputs:      0 |1  2  3  4  5  6  7  8  9  10 11 12 13|0  0
                   |________________|
                                  |_________________|
                                                 |________________|
    

In this example:

  • Input width = 13
  • Filter width = 6
  • Stride = 5

Notes:

  • "VALID" only ever drops the right-most columns (or bottom-most rows).
  • "SAME" tries to pad evenly left and right, but if the amount of columns to be added is odd, it will add the extra column to the right, as is the case in this example (the same logic applies vertically: there may be an extra row of zeros at the bottom).

Edit:

About the name:

  • With "SAME" padding, if you use a stride of 1, the layer’s outputs will have the same spatial dimensions as its inputs.
  • With "VALID" padding, there’s no “made-up” padding inputs. The layer only uses valid input data.

回答 2

stride为1时(卷积比池化更典型),我们可以想到以下区别:

  • "SAME":输出大小输入大小相同。这要求过滤器窗口滑到输入图的外部,因此需要填充。
  • "VALID":过滤器窗口停留在输入地图内的有效位置,因此输出大小缩小filter_size - 1。没有填充发生。

When stride is 1 (more typical with convolution than pooling), we can think of the following distinction:

  • "SAME": output size is the same as input size. This requires the filter window to slip outside input map, hence the need to pad.
  • "VALID": Filter window stays at valid position inside input map, so output size shrinks by filter_size - 1. No padding occurs.

回答 3

所述TensorFlow卷积示例给出关于之间的差的概述SAMEVALID

  • 对于SAME填充,输出高度和宽度的计算公式如下:

    out_height = ceil(float(in_height) / float(strides[1]))
    out_width  = ceil(float(in_width) / float(strides[2]))

  • 对于VALID填充,输出高度和宽度的计算公式如下:

    out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
    out_width  = ceil(float(in_width - filter_width + 1) / float(strides[2]))

The TensorFlow Convolution example gives an overview about the difference between SAME and VALID :

  • For the SAME padding, the output height and width are computed as:

    out_height = ceil(float(in_height) / float(strides[1]))
    out_width  = ceil(float(in_width) / float(strides[2]))
    

And

  • For the VALID padding, the output height and width are computed as:

    out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
    out_width  = ceil(float(in_width - filter_width + 1) / float(strides[2]))
    

回答 4

填充是增加输入数据大小的操作。如果是一维数据,则只需在数组上附加/添加常量,在二维中,将这些常量包围在矩阵中。在n-dim中,将常数包围在n-dim超立方体中。在大多数情况下,此常数为零,称为零填充。

这是一个p=1应用于2-d张量的零填充示例: 在此处输入图片说明


您可以对内核使用任意填充,但是某些填充值的使用频率要比其他填充值高:

  • 有效填充。最简单的情况是完全没有填充。只需保持数据不变即可。
  • 相同的填充有时也称为HALF填充。之所以称为SAME,是因为对于步幅= 1的卷积(或对于池化),它应产生与输入大小相同的输出。之所以称为HALF,是因为对于一个大小的内核k 在此处输入图片说明
  • 全填充是最大填充,不会导致仅填充元素的卷积。对于内核大小k,此填充等于k - 1

要在TF中使用任意填充,您可以使用 tf.pad()

Padding is an operation to increase the size of the input data. In case of 1-dimensional data you just append/prepend the array with a constant, in 2-dim you surround matrix with these constants. In n-dim you surround your n-dim hypercube with the constant. In most of the cases this constant is zero and it is called zero-padding.

Here is an example of zero-padding with p=1 applied to 2-d tensor: enter image description here


You can use arbitrary padding for your kernel but some of the padding values are used more frequently than others they are:

  • VALID padding. The easiest case, means no padding at all. Just leave your data the same it was.
  • SAME padding sometimes called HALF padding. It is called SAME because for a convolution with a stride=1, (or for pooling) it should produce output of the same size as the input. It is called HALF because for a kernel of size k enter image description here
  • FULL padding is the maximum padding which does not result in a convolution over just padded elements. For a kernel of size k, this padding is equal to k - 1.

To use arbitrary padding in TF, you can use tf.pad()


回答 5

快速说明

VALID:不要应用任何填充,即假设所有尺寸均有效,以便输入图像完全被您指定的过滤器和步幅覆盖。

SAME:对输入使用填充(如果需要),以使输入图像完全被滤镜覆盖,并跨步指定。对于第1步,这将确保输出图像大小相同输入。

笔记

  • 这同样适用于转换层和最大池层
  • 术语“有效”有点用词不当,因为如果您删除部分图像,事情不会变得“无效”。有时您甚至可能想要那样。这应该被称为NO_PADDING改为。
  • 术语“相同”也是错误的称呼,因为只有当输出尺寸与输入尺寸相同时,步幅为1才有意义。例如,对于跨度为2的步,输出尺寸将为一半。应该应该AUTO_PADDING改为调用它。
  • SAME(即自动填充模式)下,Tensorflow将尝试在左右两侧均匀地填充填充。
  • VALID(即无填充模式)下,如果您的过滤器和步幅未完全覆盖输入图像,Tensorflow将在右边和/或底部单元格下降。

Quick Explanation

VALID: Don’t apply any padding, i.e., assume that all dimensions are valid so that input image fully gets covered by filter and stride you specified.

SAME: Apply padding to input (if needed) so that input image gets fully covered by filter and stride you specified. For stride 1, this will ensure that output image size is same as input.

Notes

  • This applies to conv layers as well as max pool layers in same way
  • The term “valid” is bit of a misnomer because things don’t become “invalid” if you drop part of the image. Sometime you might even want that. This should have probably be called NO_PADDING instead.
  • The term “same” is a misnomer too because it only makes sense for stride of 1 when output dimension is same as input dimension. For stride of 2, output dimensions will be half, for example. This should have probably be called AUTO_PADDING instead.
  • In SAME (i.e. auto-pad mode), Tensorflow will try to spread padding evenly on both left and right.
  • In VALID (i.e. no padding mode), Tensorflow will drop right and/or bottom cells if your filter and stride doesn’t full cover input image.

回答 6

我引用官方tensorflow文档https://www.tensorflow.org/api_guides/python/nn#Convolution的答案 对于’SAME’填充,输出高度和宽度的计算方式如下:

out_height = ceil(float(in_height) / float(strides[1]))
out_width  = ceil(float(in_width) / float(strides[2]))

和顶部和左侧的填充计算为:

pad_along_height = max((out_height - 1) * strides[1] +
                    filter_height - in_height, 0)
pad_along_width = max((out_width - 1) * strides[2] +
                   filter_width - in_width, 0)
pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left

对于“有效”填充,输出高度和宽度的计算公式如下:

out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width  = ceil(float(in_width - filter_width + 1) / float(strides[2]))

填充值始终为零。

I am quoting this answer from official tensorflow docs https://www.tensorflow.org/api_guides/python/nn#Convolution For the ‘SAME’ padding, the output height and width are computed as:

out_height = ceil(float(in_height) / float(strides[1]))
out_width  = ceil(float(in_width) / float(strides[2]))

and the padding on the top and left are computed as:

pad_along_height = max((out_height - 1) * strides[1] +
                    filter_height - in_height, 0)
pad_along_width = max((out_width - 1) * strides[2] +
                   filter_width - in_width, 0)
pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left

For the ‘VALID’ padding, the output height and width are computed as:

out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width  = ceil(float(in_width - filter_width + 1) / float(strides[2]))

and the padding values are always zero.


回答 7

填充有三种选择:有效(无填充),相同(或一半),完整。您可以在以下位置找到说明(在Theano中):http : //deeplearning.net/software/theano/tutorial/conv_arithmetic.html

  • 有效或无填充:

有效填充不涉及零填充,因此它仅覆盖有效输入,不包括人工生成的零。如果步幅s = 1,则对于内核大小k,输出的长度为((输入的长度)-(k-1))。

  • 相同或一半填充:

当s = 1时,相同的填充使输出的大小与输入的大小相同。如果s = 1,则填充的零数为(k-1)。

  • 全填充:

完全填充意味着内核将在整个输入上运行,因此,在最后,内核可能会遇到唯一的一个输入,而其他输入可能为零。如果s = 1,则填充的零数为2(k-1)。如果s = 1,则输出长度为((输入长度​​)+(k-1))。

因此,填充数:(有效)<=(相同)<=(满)

There are three choices of padding: valid (no padding), same (or half), full. You can find explanations (in Theano) here: http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html

  • Valid or no padding:

The valid padding involves no zero padding, so it covers only the valid input, not including artificially generated zeros. The length of output is ((the length of input) – (k-1)) for the kernel size k if the stride s=1.

  • Same or half padding:

The same padding makes the size of outputs be the same with that of inputs when s=1. If s=1, the number of zeros padded is (k-1).

  • Full padding:

The full padding means that the kernel runs over the whole inputs, so at the ends, the kernel may meet the only one input and zeros else. The number of zeros padded is 2(k-1) if s=1. The length of output is ((the length of input) + (k-1)) if s=1.

Therefore, the number of paddings: (valid) <= (same) <= (full)


回答 8

启用/禁用填充。确定输入的有效大小。

VALID:没有填充。卷积运算等操作仅在“有效”的位置执行,即不太靠近张量的边界。
使用3×3的内核和10×10的图像,您将在边界内的8×8区域执行卷积。

SAME:提供填充。每当您的操作引用邻域(无论大小)时,当该邻域超出原始张量时,都会提供零值,以使该操作也可以处理边界值。
使用3×3的内核和10×10的图像,您将在整个10×10区域上进行卷积。

Padding on/off. Determines the effective size of your input.

VALID: No padding. Convolution etc. ops are only performed at locations that are “valid”, i.e. not too close to the borders of your tensor.
With a kernel of 3×3 and image of 10×10, you would be performing convolution on the 8×8 area inside the borders.

SAME: Padding is provided. Whenever your operation references a neighborhood (no matter how big), zero values are provided when that neighborhood extends outside the original tensor to allow that operation to work also on border values.
With a kernel of 3×3 and image of 10×10, you would be performing convolution on the full 10×10 area.


回答 9

有效填充:这是零填充。希望没有混乱。

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
print (valid_pad.get_shape()) # output-->(1, 2, 1, 1)

相同的 填充:首先要理解这有点棘手,因为我们必须分别考虑两个条件,如官方文档中所述

让我们将输入设为,将输出设为,将填充设为,将步幅设为,将内核大小设为(仅考虑一个维度)

情况01 ::

情况02 ::

计算出使得填充可用的最小值。由于的值是已知的,因此可以使用此公式找到的值

让我们算出这个例子:

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
print (same_pad.get_shape()) # --> output (1, 2, 2, 1)

x的维数为(3,4)。然后,如果采取水平方向(3):

如果采用垂直方向(4):

希望这将有助于理解SAME填充在TF中的实际作用。

VALID padding: this is with zero padding. Hope there is no confusion.

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
print (valid_pad.get_shape()) # output-->(1, 2, 1, 1)

SAME padding: This is kind of tricky to understand in the first place because we have to consider two conditions separately as mentioned in the official docs.

Let’s take input as , output as , padding as , stride as and kernel size as (only a single dimension is considered)

Case 01: :

Case 02: :

is calculated such that the minimum value which can be taken for padding. Since value of is known, value of can be found using this formula .

Let’s work out this example:

x = tf.constant([[1., 2., 3.], [4., 5., 6.],[ 7., 8., 9.], [ 7., 8., 9.]])
x = tf.reshape(x, [1, 4, 3, 1])
same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
print (same_pad.get_shape()) # --> output (1, 2, 2, 1)

Here the dimension of x is (3,4). Then if the horizontal direction is taken (3):

If the vertial direction is taken (4):

Hope this will help to understand how actually SAME padding works in TF.


回答 10

根据此处的说明以及Tristan的回答,我通常使用这些快速功能进行健全性检查。

# a function to help us stay clean
def getPaddings(pad_along_height,pad_along_width):
    # if even.. easy..
    if pad_along_height%2 == 0:
        pad_top = pad_along_height / 2
        pad_bottom = pad_top
    # if odd
    else:
        pad_top = np.floor( pad_along_height / 2 )
        pad_bottom = np.floor( pad_along_height / 2 ) +1
    # check if width padding is odd or even
    # if even.. easy..
    if pad_along_width%2 == 0:
        pad_left = pad_along_width / 2
        pad_right= pad_left
    # if odd
    else:
        pad_left = np.floor( pad_along_width / 2 )
        pad_right = np.floor( pad_along_width / 2 ) +1
        #
    return pad_top,pad_bottom,pad_left,pad_right

# strides [image index, y, x, depth]
# padding 'SAME' or 'VALID'
# bottom and right sides always get the one additional padded pixel (if padding is odd)
def getOutputDim (inputWidth,inputHeight,filterWidth,filterHeight,strides,padding):
    if padding == 'SAME':
        out_height = np.ceil(float(inputHeight) / float(strides[1]))
        out_width  = np.ceil(float(inputWidth) / float(strides[2]))
        #
        pad_along_height = ((out_height - 1) * strides[1] + filterHeight - inputHeight)
        pad_along_width = ((out_width - 1) * strides[2] + filterWidth - inputWidth)
        #
        # now get padding
        pad_top,pad_bottom,pad_left,pad_right = getPaddings(pad_along_height,pad_along_width)
        #
        print 'output height', out_height
        print 'output width' , out_width
        print 'total pad along height' , pad_along_height
        print 'total pad along width' , pad_along_width
        print 'pad at top' , pad_top
        print 'pad at bottom' ,pad_bottom
        print 'pad at left' , pad_left
        print 'pad at right' ,pad_right

    elif padding == 'VALID':
        out_height = np.ceil(float(inputHeight - filterHeight + 1) / float(strides[1]))
        out_width  = np.ceil(float(inputWidth - filterWidth + 1) / float(strides[2]))
        #
        print 'output height', out_height
        print 'output width' , out_width
        print 'no padding'


# use like so
getOutputDim (80,80,4,4,[1,1,1,1],'SAME')

Based on the explanation here and following up on Tristan’s answer, I usually use these quick functions for sanity checks.

# a function to help us stay clean
def getPaddings(pad_along_height,pad_along_width):
    # if even.. easy..
    if pad_along_height%2 == 0:
        pad_top = pad_along_height / 2
        pad_bottom = pad_top
    # if odd
    else:
        pad_top = np.floor( pad_along_height / 2 )
        pad_bottom = np.floor( pad_along_height / 2 ) +1
    # check if width padding is odd or even
    # if even.. easy..
    if pad_along_width%2 == 0:
        pad_left = pad_along_width / 2
        pad_right= pad_left
    # if odd
    else:
        pad_left = np.floor( pad_along_width / 2 )
        pad_right = np.floor( pad_along_width / 2 ) +1
        #
    return pad_top,pad_bottom,pad_left,pad_right

# strides [image index, y, x, depth]
# padding 'SAME' or 'VALID'
# bottom and right sides always get the one additional padded pixel (if padding is odd)
def getOutputDim (inputWidth,inputHeight,filterWidth,filterHeight,strides,padding):
    if padding == 'SAME':
        out_height = np.ceil(float(inputHeight) / float(strides[1]))
        out_width  = np.ceil(float(inputWidth) / float(strides[2]))
        #
        pad_along_height = ((out_height - 1) * strides[1] + filterHeight - inputHeight)
        pad_along_width = ((out_width - 1) * strides[2] + filterWidth - inputWidth)
        #
        # now get padding
        pad_top,pad_bottom,pad_left,pad_right = getPaddings(pad_along_height,pad_along_width)
        #
        print 'output height', out_height
        print 'output width' , out_width
        print 'total pad along height' , pad_along_height
        print 'total pad along width' , pad_along_width
        print 'pad at top' , pad_top
        print 'pad at bottom' ,pad_bottom
        print 'pad at left' , pad_left
        print 'pad at right' ,pad_right

    elif padding == 'VALID':
        out_height = np.ceil(float(inputHeight - filterHeight + 1) / float(strides[1]))
        out_width  = np.ceil(float(inputWidth - filterWidth + 1) / float(strides[2]))
        #
        print 'output height', out_height
        print 'output width' , out_width
        print 'no padding'


# use like so
getOutputDim (80,80,4,4,[1,1,1,1],'SAME')

回答 11

综上所述,“有效”填充表示没有填充。卷积层的输出大小根据输入大小和内核大小而缩小。

相反,“相同”填充表示使用填充。当跨度设置为1时,在计算卷积时,通过在输入数据周围附加一定数量的“ 0边界”,将卷积层的输出大小保持为输入大小。

希望这种直观的描述有所帮助。

To sum up, ‘valid’ padding means no padding. The output size of the convolutional layer shrinks depending on the input size & kernel size.

On the contrary, ‘same’ padding means using padding. When the stride is set as 1, the output size of the convolutional layer maintains as the input size by appending a certain number of ‘0-border’ around the input data when calculating convolution.

Hope this intuitive description helps.


回答 12

通式

此处,W和H是输入的宽度和高度,F是过滤器尺寸,P是填充大小(即,要填充的行数或列数)

对于相同的填充:

相同的填充

对于有效填充:

有效填充

General Formula

Here, W and H are width and height of input, F are filter dimensions, P is padding size (i.e., number of rows or columns to be padded)

For SAME padding:

SAME Padding

For VALID padding:

VALID padding


回答 13

补充YvesgereY的好答案,我发现此可视化非常有用:

填充可视化

填充有效 ”是第一个数字。过滤器窗口停留在图像内部。

填充“ 相同 ”是第三个数字。输出大小相同。


本文上找到它。

Complementing YvesgereY’s great answer, I found this visualization extremely helpful:

Padding visualization

Padding ‘valid‘ is the first figure. The filter window stays inside the image.

Padding ‘same‘ is the third figure. The output is the same size.


Found it on this article.


回答 14

Tensorflow 2.0兼容答案:上面已经提供了有关“有效”和“相同”填充的详细说明。

但是,Tensorflow 2.x (>= 2.0)为了社区的利益,我将在中指定不同的Pooling Function及其各自的Command 。

1.x中的功能

tf.nn.max_pool

tf.keras.layers.MaxPool2D

Average Pooling => None in tf.nn, tf.keras.layers.AveragePooling2D

2.x中的功能

tf.nn.max_pool如果在2.x和tf.compat.v1.nn.max_pool_v2或中使用tf.compat.v2.nn.max_pool,则从1.x迁移到2.x。

tf.keras.layers.MaxPool2D 如果在2.x和

tf.compat.v1.keras.layers.MaxPool2Dtf.compat.v1.keras.layers.MaxPooling2Dtf.compat.v2.keras.layers.MaxPool2Dtf.compat.v2.keras.layers.MaxPooling2D(如果从1.x迁移到2.x)。

Average Pooling => tf.nn.avg_pool2d或者tf.keras.layers.AveragePooling2D在TF 2.x中使用

tf.compat.v1.nn.avg_pool_v2tf.compat.v2.nn.avg_pooltf.compat.v1.keras.layers.AveragePooling2Dtf.compat.v1.keras.layers.AvgPool2Dtf.compat.v2.keras.layers.AveragePooling2Dtf.compat.v2.keras.layers.AvgPool2D,如果从1.x中迁移到2.x版本

有关从Tensorflow 1.x迁移到2.x的更多信息,请参阅此迁移指南

Tensorflow 2.0 Compatible Answer: Detailed Explanations have been provided above, about “Valid” and “Same” Padding.

However, I will specify different Pooling Functions and their respective Commands in Tensorflow 2.x (>= 2.0), for the benefit of the community.

Functions in 1.x:

tf.nn.max_pool

tf.keras.layers.MaxPool2D

Average Pooling => None in tf.nn, tf.keras.layers.AveragePooling2D

Functions in 2.x:

tf.nn.max_pool if used in 2.x and tf.compat.v1.nn.max_pool_v2 or tf.compat.v2.nn.max_pool, if migrated from 1.x to 2.x.

tf.keras.layers.MaxPool2D if used in 2.x and

tf.compat.v1.keras.layers.MaxPool2D or tf.compat.v1.keras.layers.MaxPooling2D or tf.compat.v2.keras.layers.MaxPool2D or tf.compat.v2.keras.layers.MaxPooling2D, if migrated from 1.x to 2.x.

Average Pooling => tf.nn.avg_pool2d or tf.keras.layers.AveragePooling2D if used in TF 2.x and

tf.compat.v1.nn.avg_pool_v2 or tf.compat.v2.nn.avg_pool or tf.compat.v1.keras.layers.AveragePooling2D or tf.compat.v1.keras.layers.AvgPool2D or tf.compat.v2.keras.layers.AveragePooling2D or tf.compat.v2.keras.layers.AvgPool2D , if migrated from 1.x to 2.x.

For more information about Migration from Tensorflow 1.x to 2.x, please refer to this Migration Guide.


最喜欢的Django提示和功能?

问题:最喜欢的Django提示和功能?

受问题系列“ …的隐藏功能”的启发,我很想知道您最喜欢的Django提示或您所知的鲜为人知但有用的功能。

  • 请每个答案仅包含一个提示。
  • 添加Django版本要求(如果有)。

Inspired by the question series ‘Hidden features of …’, I am curious to hear about your favorite Django tips or lesser known but useful features you know of.

  • Please, include only one tip per answer.
  • Add Django version requirements if there are any.

回答 0

我将从我自己的提示开始:)

在settings.py中使用os.path.dirname()避免使用硬编码的目录名。

如果要在其他位置运行项目,请不要在settings.py中硬编码路径。如果您的模板和静态文件位于Django项目目录中,请在settings.py中使用以下代码:

# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, "templates"),
)

鸣谢:我从屏幕录像“ Django From the Ground Up ” 获得了这个技巧。

I’m just going to start with a tip from myself :)

Use os.path.dirname() in settings.py to avoid hardcoded dirnames.

Don’t hardcode path’s in your settings.py if you want to run your project in different locations. Use the following code in settings.py if your templates and static files are located within the Django project directory:

# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, "templates"),
)

Credits: I got this tip from the screencast ‘Django From the Ground Up‘.


回答 1

安装Django Command Extensionspygraphviz,然后发出以下命令以获取非常漂亮的Django模型可视化效果:

./manage.py graph_models -a -g -o my_project.png

Install Django Command Extensions and pygraphviz and then issue the following command to get a really nice looking Django model visualization:

./manage.py graph_models -a -g -o my_project.png

回答 2

使用django-annoying的 render_to装饰器代替render_to_response

@render_to('template.html')
def foo(request):
    bars = Bar.objects.all()
    if request.user.is_authenticated():
        return HttpResponseRedirect("/some/url/")
    else:
        return {'bars': bars}

# equals to
def foo(request):
    bars = Bar.objects.all()
    if request.user.is_authenticated():
        return HttpResponseRedirect("/some/url/")
    else:
        return render_to_response('template.html',
                              {'bars': bars},
                              context_instance=RequestContext(request))

编辑指出,返回HttpResponse(例如重定向)将使装饰器短路并按预期工作。

Use django-annoying’s render_to decorator instead of render_to_response.

@render_to('template.html')
def foo(request):
    bars = Bar.objects.all()
    if request.user.is_authenticated():
        return HttpResponseRedirect("/some/url/")
    else:
        return {'bars': bars}

# equals to
def foo(request):
    bars = Bar.objects.all()
    if request.user.is_authenticated():
        return HttpResponseRedirect("/some/url/")
    else:
        return render_to_response('template.html',
                              {'bars': bars},
                              context_instance=RequestContext(request))

Edited to point out that returning an HttpResponse (such as a redirect) will short circuit the decorator and work just as you expect.


回答 3

我在网站的所有模板上使用了一组自定义标签。在寻找一种自动加载的方式(DRY,还记得吗?),我发现了以下内容:

from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')

如果将其放在默认情况下加载的模块(例如您的主urlconf)中,则可以在任何模板中使用自定义标签模块中的标签和过滤器,而无需使用 {% load custom_tag_module %}

传递给的参数template.add_to_builtins()可以是任何模块路径;您的自定义标签模块不必位于特定的应用程序中。例如,它也可以是项目根目录中的模块(例如'project.custom_tag_module')。

There’s a set of custom tags I use all over my site’s templates. Looking for a way to autoload it (DRY, remember?), I found the following:

from django import template
template.add_to_builtins('project.app.templatetags.custom_tag_module')

If you put this in a module that’s loaded by default (your main urlconf for instance), you’ll have the tags and filters from your custom tag module available in any template, without using {% load custom_tag_module %}.

The argument passed to template.add_to_builtins() can be any module path; your custom tag module doesn’t have to live in a specific application. For example, it can also be a module in your project’s root directory (eg. 'project.custom_tag_module').


回答 4

如果您正在处理多个Django项目,则Virtualenv + Python = life saver,并且它们有可能不都依赖于同一版本的Django /应用程序。

Virtualenv + Python = life saver if you are working on multiple Django projects and there is a possibility that they all don’t depend on the same version of Django/an application.


回答 5

不要对您的网址进行硬编码!

请改用网址名称,然后reverse函数来获取URL本身。

定义URL映射时,请为URL命名。

urlpatterns += ('project.application.views'
   url( r'^something/$', 'view_function', name="url-name" ),
   ....
)

确保每个URL的名称都是唯一的。

我通常使用一致的格式“ project-appplication-view”,例如用于线程视图的“ cbx-forum-thread”。

更新(无耻地窃取ayaz的附加内容):

可以在带有url标记的模板中使用该名称。

Don’t hard-code your URLs!

Use url names instead, and the reverse function to get the URL itself.

When you define your URL mappings, give names to your URLs.

urlpatterns += ('project.application.views'
   url( r'^something/$', 'view_function', name="url-name" ),
   ....
)

Make sure the name is unique per URL.

I usually have a consistent format “project-appplication-view”, e.g. “cbx-forum-thread” for a thread view.

UPDATE (shamelessly stealing ayaz’s addition):

This name can be used in templates with the url tag.


回答 6

使用django调试工具栏。例如,它允许查看在呈现视图时执行的所有SQL查询,还可以查看其中任何一个的stacktrace。

Use django debug toolbar. For example, it allows to view all SQL queries performed while rendering view and you can also view stacktrace for any of them.


回答 7

不要编写自己的登录页面。如果您使用的是django.contrib.auth。

真正的肮脏秘密是,如果您还使用django.contrib.admin,并且django.template.loaders.app_directories.load_template_source位于模板加载器中, 那么您也可以免费获得模板!

# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
    (r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
    (r'^accounts/logout/$','views.logout'),
)

Don’t write your own login pages. If you’re using django.contrib.auth.

The real, dirty secret is that if you’re also using django.contrib.admin, and django.template.loaders.app_directories.load_template_source is in your template loaders, you can get your templates free too!

# somewhere in urls.py
urlpatterns += patterns('django.contrib.auth',
    (r'^accounts/login/$','views.login', {'template_name': 'admin/login.html'}),
    (r'^accounts/logout/$','views.logout'),
)

回答 8

上下文处理器很棒。

假设您有一个不同的用户模型,并且希望将其包含在每个响应中。而不是这样做:

def myview(request, arg, arg2=None, template='my/template.html'):
    ''' My view... '''
    response = dict()
    myuser = MyUser.objects.get(user=request.user)
    response['my_user'] = myuser
    ...
    return render_to_response(template,
                              response,
                              context_instance=RequestContext(request))

上下文过程使您能够将任何变量传递到模板。我通常把我的放在'my_project/apps/core/context.py

def my_context(request):
    try:
        return dict(my_user=MyUser.objects.get(user=request.user))
    except ObjectNotFound:
        return dict(my_user='')

在您settings.py的代码中,将以下行添加到您的TEMPLATE_CONTEXT_PROCESSORS

TEMPLATE_CONTEXT_PROCESSORS = (
    'my_project.apps.core.context.my_context',
    ...
)

现在,每次发出请求时,它都会my_user自动包含密钥。

信号赢了。

几个月前,我写了一篇有关此的博客文章,所以我要剪切粘贴:

Django开箱即用地为您提供了许多非常有用的信号。您可以在保存,初始化,删除甚至处理请求之前和之后进行操作。因此,让我们远离这些概念并演示如何使用它们。说我们有一个博客

from django.utils.translation import ugettext_lazy as _
class Post(models.Model):
    title = models.CharField(_('title'), max_length=255)
    body = models.TextField(_('body'))
    created = models.DateTimeField(auto_now_add=True)

因此,您想以某种方式通知我们已发布新帖子的众多Blog Ping服务之一,重建最新的帖子缓存,并对其进行鸣叫。有了信号,您就可以执行所有这些操作而不必向Post类添加任何方法。

import twitter

from django.core.cache import cache
from django.db.models.signals import post_save
from django.conf import settings

def posted_blog(sender, created=None, instance=None, **kwargs):
    ''' Listens for a blog post to save and alerts some services. '''
    if (created and instance is not None):
        tweet = 'New blog post! %s' instance.title
        t = twitter.PostUpdate(settings.TWITTER_USER,
                               settings.TWITTER_PASSWD,
                               tweet)
        cache.set(instance.cache_key, instance, 60*5)
       # send pingbacks
       # ...
       # whatever else
    else:
        cache.delete(instance.cache_key)
post_save.connect(posted_blog, sender=Post)

通过定义该函数并使用post_init信号将函数连接到Post模型,然后在保存后执行该函数,我们就可以了。

Context processors are awesome.

Say you have a different user model and you want to include that in every response. Instead of doing this:

def myview(request, arg, arg2=None, template='my/template.html'):
    ''' My view... '''
    response = dict()
    myuser = MyUser.objects.get(user=request.user)
    response['my_user'] = myuser
    ...
    return render_to_response(template,
                              response,
                              context_instance=RequestContext(request))

Context processes give you the ability to pass any variable to your templates. I typically put mine in 'my_project/apps/core/context.py:

def my_context(request):
    try:
        return dict(my_user=MyUser.objects.get(user=request.user))
    except ObjectNotFound:
        return dict(my_user='')

In your settings.py add the following line to your TEMPLATE_CONTEXT_PROCESSORS

TEMPLATE_CONTEXT_PROCESSORS = (
    'my_project.apps.core.context.my_context',
    ...
)

Now every time a request is made it includes the my_user key automatically.

Also signals win.

I wrote a blog post about this a few months ago so I’m just going to cut and paste:

Out of the box Django gives you several signals that are incredibly useful. You have the ability to do things pre and post save, init, delete, or even when a request is being processed. So lets get away from the concepts and demonstrate how these are used. Say we’ve got a blog

from django.utils.translation import ugettext_lazy as _
class Post(models.Model):
    title = models.CharField(_('title'), max_length=255)
    body = models.TextField(_('body'))
    created = models.DateTimeField(auto_now_add=True)

So somehow you want to notify one of the many blog-pinging services we’ve made a new post, rebuild the most recent posts cache, and tweet about it. Well with signals you have the ability to do all of this without having to add any methods to the Post class.

import twitter

from django.core.cache import cache
from django.db.models.signals import post_save
from django.conf import settings

def posted_blog(sender, created=None, instance=None, **kwargs):
    ''' Listens for a blog post to save and alerts some services. '''
    if (created and instance is not None):
        tweet = 'New blog post! %s' instance.title
        t = twitter.PostUpdate(settings.TWITTER_USER,
                               settings.TWITTER_PASSWD,
                               tweet)
        cache.set(instance.cache_key, instance, 60*5)
       # send pingbacks
       # ...
       # whatever else
    else:
        cache.delete(instance.cache_key)
post_save.connect(posted_blog, sender=Post)

There we go, by defining that function and using the post_init signal to connect the function to the Post model and execute it after it has been saved.


回答 9

当我刚开始的时候,我不知道有一个分页器,请确保您知道它的存在!

When I was starting out, I didn’t know that there was a Paginator, make sure you know of its existence!!


回答 10

使用IPython可以进入任何级别的代码,并使用IPython的功能进行调试。一旦安装了IPython,就可以将此代码放到要调试的位置:

from IPython.Shell import IPShellEmbed; IPShellEmbed()()

然后,刷新页面,转到runserver窗口,您将进入交互式IPython窗口。

我在TextMate中设置了一个代码段,所以我只需键入ipshell并单击Tab。没有它,我活不下去。

Use IPython to jump into your code at any level and debug using the power of IPython. Once you have installed IPython just put this code in wherever you want to debug:

from IPython.Shell import IPShellEmbed; IPShellEmbed()()

Then, refresh the page, go to your runserver window and you will be in an interactive IPython window.

I have a snippet set up in TextMate so I just type ipshell and hit tab. I couldn’t live without it.


回答 11

运行开发SMTP服务器,该服务器将仅输出发送给它的任何内容(如果您不想在开发服务器上实际安装SMTP)。

命令行:

python -m smtpd -n -c DebuggingServer localhost:1025

Run a development SMTP server that will just output whatever is sent to it (if you don’t want to actually install SMTP on your dev server.)

command line:

python -m smtpd -n -c DebuggingServer localhost:1025

回答 12

django-admin文档中

如果使用Bash shell,请考虑安装Django bash完成脚本,该脚本extras/django_bash_completion位于Django发行版中。它启用django-admin.pymanage.py命令的制表符补全,因此您可以例如…

  • 类型 django-admin.py
  • 按[TAB]查看所有可用选项。
  • 键入sql,然后按[TAB],以查看名称以开头的所有可用选项sql

From the django-admin documentation:

If you use the Bash shell, consider installing the Django bash completion script, which lives in extras/django_bash_completion in the Django distribution. It enables tab-completion of django-admin.py and manage.py commands, so you can, for instance…

  • Type django-admin.py.
  • Press [TAB] to see all available options.
  • Type sql, then [TAB], to see all available options whose names start with sql.

回答 13

./manage.py runserver_plus附带facilty django_extensions是真正真棒。

它创建了一个增强的调试页面,除其他外,该页面使用Werkzeug调试器为堆栈中的每个点创建交互式调试控制台(请参见屏幕截图)。它还提供了一种非常有用的便捷调试方法,dump()用于显示有关对象/框架的信息。

在此处输入图片说明

要安装,您可以使用pip:

pip install django_extensions
pip install Werkzeug

然后添加'django_extensions'到您的INSTALLED_APPS元组中,settings.py并使用新扩展名启动开发服务器:

./manage.py runserver_plus

这将改变您的调试方式。

The ./manage.py runserver_plus facilty which comes with django_extensions is truly awesome.

It creates an enhanced debug page that, amongst other things, uses the Werkzeug debugger to create interactive debugging consoles for each point in the stack (see screenshot). It also provides a very useful convenience debugging method dump() for displaying information about an object/frame.

enter image description here

To install, you can use pip:

pip install django_extensions
pip install Werkzeug

Then add 'django_extensions' to your INSTALLED_APPS tuple in settings.py and start the development server with the new extension:

./manage.py runserver_plus

This will change the way you debug.


回答 14

我喜欢使用Python调试器pdb调试Django项目。

这是学习使用方法的有用链接:http : //www.ferg.org/papers/debugging_in_python.html

I like to use the Python debugger pdb to debug Django projects.

This is a helpful link for learning how to use it: http://www.ferg.org/papers/debugging_in_python.html


回答 15

尝试在Django和另一个应用程序之间交换数据时,request.raw_post_data是个好朋友。用它来接收和定制处理XML数据。

文档:http : //docs.djangoproject.com/en/dev/ref/request-response/

When trying to exchange data between Django and another application, request.raw_post_data is a good friend. Use it to receive and custom-process, say, XML data.

Documentation: http://docs.djangoproject.com/en/dev/ref/request-response/


回答 16

使用Jinja2与Django一起。

如果您发现Django模板语言非常严格(像我一样!),那么您不必受其限制。Django非常灵活,并且模板语言与系统的其余部分松散耦合,因此只需插入另一种模板语言并使用它来呈现您的http响应!

我使用Jinja2,它几乎像django模板语言的功能强大的版本,它使用相同的语法,并允许您在if语句中使用表达式!不再制作自定义的if标签,例如if_item_in_list!你可以简单地说%{ if item in list %},或{% if object.field < 10 %}

但这还不是全部;它具有更多的功能来简化模板的创建,尽管这里没有全部介绍。

Use Jinja2 alongside Django.

If you find the Django template language extremely restricting (like me!) then you don’t have to be stuck with it. Django is flexible, and the template language is loosely coupled to the rest of the system, so just plug-in another template language and use it to render your http responses!

I use Jinja2, it’s almost like a powered-up version of the django template language, it uses the same syntax, and allows you to use expressions in if statements! no more making a custom if-tags such as if_item_in_list! you can simply say %{ if item in list %}, or {% if object.field < 10 %}.

But that’s not all; it has many more features to ease template creation, that I can’t go though all of them in here.


回答 17

assert False在您的视图代码中添加转储调试信息。

Add assert False in your view code to dump debug information.


回答 18

这增加了上面关于Django URL名称和反向URL调度的答复

URL名称也可以在模板中有效使用。例如,对于给定的URL模式:

url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')

您可以在模板中包含以下内容:

<a href="{% url project_team project.id %}">Team</a>

This adds to the reply above about Django URL names and reverse URL dispatching.

The URL names can also be effectively used within templates. For example, for a given URL pattern:

url(r'(?P<project_id>\d+)/team/$', 'project_team', name='project_team')

you can have the following in templates:

<a href="{% url project_team project.id %}">Team</a>

回答 19

由于Django“视图”仅需要返回HttpResponse的可调用对象,因此您可以轻松地创建基于类的视图,例如Ruby on Rails和其他框架中的视图。

有几种方法可以创建基于类的视图,这是我的最爱:

from django import http

class RestView(object):
    methods = ('GET', 'HEAD')

    @classmethod
    def dispatch(cls, request, *args, **kwargs):
        resource = cls()
        if request.method.lower() not in (method.lower() for method in resource.methods):
            return http.HttpResponseNotAllowed(resource.methods)
        try:
            method = getattr(resource, request.method.lower())
        except AttributeError:
            raise Exception("View method `%s` does not exist." % request.method.lower())
        if not callable(method):
            raise Exception("View method `%s` is not callable." % request.method.lower())
        return method(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return http.HttpResponse()

    def head(self, request, *args, **kwargs):
        response = self.get(request, *args, **kwargs)
        response.content = ''
        return response

您可以在基本视图中添加各种其他内容,例如条件请求处理和授权。

设置好视图后,您的urls.py将如下所示:

from django.conf.urls.defaults import *
from views import MyRestView

urlpatterns = patterns('',
    (r'^restview/', MyRestView.dispatch),
)

Since Django “views” only need to be callables that return an HttpResponse, you can easily create class-based views like those in Ruby on Rails and other frameworks.

There are several ways to create class-based views, here’s my favorite:

from django import http

class RestView(object):
    methods = ('GET', 'HEAD')

    @classmethod
    def dispatch(cls, request, *args, **kwargs):
        resource = cls()
        if request.method.lower() not in (method.lower() for method in resource.methods):
            return http.HttpResponseNotAllowed(resource.methods)
        try:
            method = getattr(resource, request.method.lower())
        except AttributeError:
            raise Exception("View method `%s` does not exist." % request.method.lower())
        if not callable(method):
            raise Exception("View method `%s` is not callable." % request.method.lower())
        return method(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return http.HttpResponse()

    def head(self, request, *args, **kwargs):
        response = self.get(request, *args, **kwargs)
        response.content = ''
        return response

You can add all sorts of other stuff like conditional request handling and authorization in your base view.

Once you’ve got your views setup your urls.py will look something like this:

from django.conf.urls.defaults import *
from views import MyRestView

urlpatterns = patterns('',
    (r'^restview/', MyRestView.dispatch),
)

回答 20

而不是使用render_to_response将上下文绑定到模板并将其呈现(这是Django文档通常显示的内容),而是使用通用视图direct_to_template。它的功能相同,render_to_response但是它还会自动将RequestContext添加到模板上下文中,从而隐式允许使用上下文处理器。您可以使用手动进行操作render_to_response,但是为什么要麻烦呢?这只是要记住的又一个步骤和另一个LOC。除了使用上下文处理器之外,在模板中添加RequestContext还可以使您执行以下操作:

<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a> 

这非常有用。实际上,一般而言,+1是针对通用视图的。Django文档大多将它们显示为快捷方式,甚至没有简单应用程序的views.py文件,但您也可以在自己的视图函数中使用它们:

from django.views.generic import simple

def article_detail(request, slug=None):
    article = get_object_or_404(Article, slug=slug)
    return simple.direct_to_template(request, 
        template="articles/article_detail.html",
        extra_context={'article': article}
    )

Instead of using render_to_response to bind your context to a template and render it (which is what the Django docs usually show) use the generic view direct_to_template. It does the same thing that render_to_response does but it also automatically adds RequestContext to the template context, implicitly allowing context processors to be used. You can do this manually using render_to_response, but why bother? It’s just another step to remember and another LOC. Besides making use of context processors, having RequestContext in your template allows you to do things like:

<a href="{{MEDIA_URL}}images/frog.jpg">A frog</a> 

which is very useful. In fact, +1 on generic views in general. The Django docs mostly show them as shortcuts for not even having a views.py file for simple apps, but you can also use them inside your own view functions:

from django.views.generic import simple

def article_detail(request, slug=None):
    article = get_object_or_404(Article, slug=slug)
    return simple.direct_to_template(request, 
        template="articles/article_detail.html",
        extra_context={'article': article}
    )

回答 21

我没有足够的声誉来回答有问题的评论,但是请务必注意,如果您要使用Jinja,则它不支持模板块名称中的’-‘字符,而Django则支持。这给我带来了很多问题,并浪费了很多时间来跟踪它生成的非常模糊的错误消息。

I don’t have enough reputation to reply to the comment in question, but it’s important to note that if you’re going to use Jinja, it does NOT support the ‘-‘ character in template block names, while Django does. This caused me a lot of problems and wasted time trying to track down the very obscure error message it generated.


回答 22

开始设计您的网站时,webdesign应用程序非常有用。导入后,您可以添加以下内容以生成示例文本:

{% load webdesign %}
{% lorem 5 p %}

The webdesign app is very useful when starting to design your website. Once imported, you can add this to generate sample text:

{% load webdesign %}
{% lorem 5 p %}

回答 23

django.db.models.get_model 确实允许您检索模型而不导入它。

James展示了它的实用性“ Django技巧:编写更好的模板标签-迭代4”

django.db.models.get_model does allow you to retrieve a model without importing it.

James shows how handy it can be: “Django tips: Write better template tags — Iteration 4 “.


回答 24

每个人都知道有一个可以使用“ manage.py runserver”运行的开发服务器,但是您是否知道也有一个用于服务静态文件(CSS / JS / IMG)的开发视图?

新手总是感到困惑,因为Django并没有提供静态文件的任何方式。这是因为开发团队认为这是现实生活中的Web服务器的工作。

但是在开发时,您可能不想设置Apache + mod_wisgi,这很繁重。然后,您可以将以下内容添加到urls.py中:

(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': '/path/to/media'}),

您的CSS / JS / IMG将在www.yoursite.com/site_media/上提供。

当然,不要在生产环境中使用它。

Everybody knows there is a development server you can run with “manage.py runserver”, but did you know that there is a development view for serving static files (CSS / JS / IMG) as well ?

Newcomers are always puzzled because Django doesn’t come with any way to serve static files. This is because the dev team think it is the job for a real life Web server.

But when developing, you may not want to set up Apache + mod_wisgi, it’s heavy. Then you can just add the following to urls.py:

(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
        {'document_root': '/path/to/media'}),

Your CSS / JS / IMG will be available at www.yoursite.com/site_media/.

Of course, don’t use it in a production environment.


回答 25

我是从soul-thumbnails的文档中学到的应用程序。您可以在模板标签中使用“ as”关键字,以在模板中的其他位置使用调用结果。

例如:

{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>

在传递Django templatetag文档时提到了这一点,但仅引用了循环。他们并没有要求您也可以在其他任何地方使用此功能。

I learned this one from the documentation for the sorl-thumbnails app. You can use the “as” keyword in template tags to use the results of the call elsewhere in your template.

For example:

{% url image-processor uid as img_src %}
<img src="{% thumbnail img_src 100x100 %}"/>

This is mentioned in passing in the Django templatetag documentation, but in reference to loops only. They don’t call out that you can use this elsewhere (anywhere?) as well.


回答 26

django.views.generic.list_detail.object_list-它提供了用于分页的所有逻辑和模板变量(我已经写了数千次的苦工之一)。 包装它允许您需要任何逻辑。这个gem为我节省了很多时间在“搜索结果”页面中调试一次错误的调试,并在此过程中使视图代码更加整洁。

django.views.generic.list_detail.object_list — It provides all the logic & template variables for pagination (one of those I’ve-written-that-a-thousand-times-now drudgeries). Wrapping it allows for any logic you need. This gem has saved me many hours of debugging off-by-one errors in my “Search Results” pages and makes the view code cleaner in the process.


回答 27

PyCharm IDE是一个很好的代码编写环境,尤其是调试功能,并内置了对Django的支持。

PyCharm IDE is a nice environment to code and especially debug, with built-in support for Django.


回答 28

使用xml_models创建使用XML REST API后端(而不是SQL后端)的Django模型。这非常有用,尤其是在对第三方API建模时-您会获得与以前相同的所有QuerySet语法。您可以从PyPI安装它。

来自API的XML:

<profile id=4>
    <email>joe@example.com</email>
    <first_name>Joe</first_name>
    <last_name>Example</last_name>
    <date_of_birth>1975-05-15</date_of_birth>
</profile>

现在在python中:

class Profile(xml_models.Model):
    user_id = xml_models.IntField(xpath='/profile/@id')
    email = xml_models.CharField(xpath='/profile/email')
    first = xml_models.CharField(xpath='/profile/first_name')
    last = xml_models.CharField(xpath='/profile/last_name')
    birthday = xml_models.DateField(xpath='/profile/date_of_birth')

    finders = {
        (user_id,):  settings.API_URL +'/api/v1/profile/userid/%s',
        (email,):  settings.API_URL +'/api/v1/profile/email/%s',
    }

profile = Profile.objects.get(user_id=4)
print profile.email
# would print 'joe@example.com'

它还可以处理关系和集合。我们每天都在大量使用的生产代码中使用它,因此即使它是beta版,它也非常有用。它还具有一组可以在测试中使用的存根。

(免责声明:虽然我不是该库的作者,但我现在是一名提交者,做了一些次要的提交)

Use xml_models to create Django models that use an XML REST API backend (instead of a SQL one). This is very useful especially when modelling third party APIs – you get all the same QuerySet syntax that you’re used to. You can install it from PyPI.

XML from an API:

<profile id=4>
    <email>joe@example.com</email>
    <first_name>Joe</first_name>
    <last_name>Example</last_name>
    <date_of_birth>1975-05-15</date_of_birth>
</profile>

And now in python:

class Profile(xml_models.Model):
    user_id = xml_models.IntField(xpath='/profile/@id')
    email = xml_models.CharField(xpath='/profile/email')
    first = xml_models.CharField(xpath='/profile/first_name')
    last = xml_models.CharField(xpath='/profile/last_name')
    birthday = xml_models.DateField(xpath='/profile/date_of_birth')

    finders = {
        (user_id,):  settings.API_URL +'/api/v1/profile/userid/%s',
        (email,):  settings.API_URL +'/api/v1/profile/email/%s',
    }

profile = Profile.objects.get(user_id=4)
print profile.email
# would print 'joe@example.com'

It can also handle relationships and collections. We use it every day in heavily used production code, so even though it’s beta it’s very usable. It also has a good set of stubs that you can use in your tests.

(Disclaimer: while I’m not the author of this library, I am now a committer, having made a few minor commits)


回答 29

使用数据库迁移。使用南方

Use database migrations. Use South.