标签归档:python-c-api

Python(和Python C API):__new__与__init__

问题:Python(和Python C API):__new__与__init__

我要问的问题似乎是Python对__new__和__init__的重复使用?,但无论如何,我仍然不清楚__new__和之间的实际区别是什么__init__

在您急于告诉我__new__创建对象和__init__初始化对象之前,请让我明确:我明白了。 实际上,这种区分对我来说是很自然的,因为我在C ++中有经验,在那里我们放置了new,它类似地将对象分配与初始化分开。

Python的C API教程解释它是这样的:

新成员负责创建(而不是初始化)该类型的对象。它在Python中作为__new__()方法公开。… 实施新方法的原因之一是要确保实例变量的初始值

所以,是的-我明白__new__,但是尽管如此,我仍然不明白为什么它在Python中很有用。给出的示例说,__new__如果要“确保实例变量的初始值” ,这可能会很有用。好吧,这不正是要做__init__什么吗?

在C API教程中,显示​​了一个示例,其中创建了新的Type(称为“ Noddy”),并__new__定义了Type的功能。Noddy类型包含一个名为的字符串成员first,并且该字符串成员被初始化为一个空字符串,如下所示:

static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    .....

    self->first = PyString_FromString("");
    if (self->first == NULL)
    {
       Py_DECREF(self);
       return NULL;
    }

    .....
}

请注意,如果没有在此__new__定义的方法,我们将不得不使用PyType_GenericNew,它只会将所有实例变量成员初始化为NULL。因此,该__new__方法的唯一好处是实例变量将从一个空字符串开始,而不是NULL。 但是,为什么这会有用呢,因为如果我们要确保将实例变量初始化为某个默认值,那么我们可以在__init__方法中做到这一点?

The question I’m about to ask seems to be a duplicate of Python’s use of __new__ and __init__?, but regardless, it’s still unclear to me exactly what the practical difference between __new__ and __init__ is.

Before you rush to tell me that __new__ is for creating objects and __init__ is for initializing objects, let me be clear: I get that. In fact, that distinction is quite natural to me, since I have experience in C++ where we have placement new, which similarly separates object allocation from initialization.

The Python C API tutorial explains it like this:

The new member is responsible for creating (as opposed to initializing) objects of the type. It is exposed in Python as the __new__() method. … One reason to implement a new method is to assure the initial values of instance variables.

So, yeah – I get what __new__ does, but despite this, I still don’t understand why it’s useful in Python. The example given says that __new__ might be useful if you want to “assure the initial values of instance variables”. Well, isn’t that exactly what __init__ will do?

In the C API tutorial, an example is shown where a new Type (called a “Noddy”) is created, and the Type’s __new__ function is defined. The Noddy type contains a string member called first, and this string member is initialized to an empty string like so:

static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    .....

    self->first = PyString_FromString("");
    if (self->first == NULL)
    {
       Py_DECREF(self);
       return NULL;
    }

    .....
}

Note that without the __new__ method defined here, we’d have to use PyType_GenericNew, which simply initializes all of the instance variable members to NULL. So the only benefit of the __new__ method is that the instance variable will start out as an empty string, as opposed to NULL. But why is this ever useful, since if we cared about making sure our instance variables are initialized to some default value, we could have just done that in the __init__ method?


回答 0

差异主要发生在可变与不可变类型之间。

__new__接受一个类型作为第一个参数,并且(通常)返回该类型的新实例。因此,它适用于可变类型和不可变类型。

__init__接受一个实例作为第一个参数,并修改该实例的属性。这不适用于不可变类型,因为它允许在创建后通过调用修改它们obj.__init__(*args)

比较的行为tuplelist

>>> x = (1, 2)
>>> x
(1, 2)
>>> x.__init__([3, 4])
>>> x # tuple.__init__ does nothing
(1, 2)
>>> y = [1, 2]
>>> y
[1, 2]
>>> y.__init__([3, 4])
>>> y # list.__init__ reinitialises the object
[3, 4]

关于它们为什么分开的原因(除了简单的历史原因):__new__方法需要一堆样板才能正确(最初的对象创建,然后记得最后返回对象)。__init__相比之下,方法非常简单,因为您只需设置需要设置的任何属性即可。

除了__init__更易于编写的方法以及上面提到的可变与不可变的区别外,还可以利用这种分离,__init__通过在中设置任何绝对必要的实例不变式,使在子类中调用父类成为可选的__new__。不过,这通常是一种可疑的做法-通常在需要时仅调用父类__init__方法会更清晰。

The difference mainly arises with mutable vs immutable types.

__new__ accepts a type as the first argument, and (usually) returns a new instance of that type. Thus it is suitable for use with both mutable and immutable types.

__init__ accepts an instance as the first argument and modifies the attributes of that instance. This is inappropriate for an immutable type, as it would allow them to be modified after creation by calling obj.__init__(*args).

Compare the behaviour of tuple and list:

>>> x = (1, 2)
>>> x
(1, 2)
>>> x.__init__([3, 4])
>>> x # tuple.__init__ does nothing
(1, 2)
>>> y = [1, 2]
>>> y
[1, 2]
>>> y.__init__([3, 4])
>>> y # list.__init__ reinitialises the object
[3, 4]

As to why they’re separate (aside from simple historical reasons): __new__ methods require a bunch of boilerplate to get right (the initial object creation, and then remembering to return the object at the end). __init__ methods, by contrast, are dead simple, since you just set whatever attributes you need to set.

Aside from __init__ methods being easier to write, and the mutable vs immutable distinction noted above, the separation can also be exploited to make calling the parent class __init__ in subclasses optional by setting up any absolutely required instance invariants in __new__. This is generally a dubious practice though – it’s usually clearer to just call the parent class __init__ methods as necessary.


回答 1

可能还有其他用途,__new__但有一个真正显而易见的用途:如果不使用,就不能继承不可变类型__new__。例如,假设您要创建一个元组的子类,该子类只能包含0到之间的整数值size

class ModularTuple(tuple):
    def __new__(cls, tup, size=100):
        tup = (int(x) % size for x in tup)
        return super(ModularTuple, cls).__new__(cls, tup)

你根本无法做到这一点__init__-如果你试图修改self__init__,解释器会抱怨你试图修改不可变对象。

There are probably other uses for __new__ but there’s one really obvious one: You can’t subclass an immutable type without using __new__. So for example, say you wanted to create a subclass of tuple that can contain only integral values between 0 and size.

class ModularTuple(tuple):
    def __new__(cls, tup, size=100):
        tup = (int(x) % size for x in tup)
        return super(ModularTuple, cls).__new__(cls, tup)

You simply can’t do this with __init__ — if you tried to modify self in __init__, the interpreter would complain that you’re trying to modify an immutable object.


回答 2

__new__()可以返回与其绑定的类不同类型的对象。__init__()仅初始化该类的现有实例。

>>> class C(object):
...   def __new__(cls):
...     return 5
...
>>> c = C()
>>> print type(c)
<type 'int'>
>>> print c
5

__new__() can return objects of types other than the class it’s bound to. __init__() only initializes an existing instance of the class.

>>> class C(object):
...   def __new__(cls):
...     return 5
...
>>> c = C()
>>> print type(c)
<type 'int'>
>>> print c
5

回答 3

这不是一个完整的答案,但也许可以说明差异。

__new__当必须创建一个对象时,它将总是被调用。在某些情况下__init__不会被呼叫。一个示例是,当您从pickle文件中解开对象时,它们将被分配(__new__)但未初始化(__init__)。

Not a complete answer but perhaps something that illustrates the difference.

__new__ will always get called when an object has to be created. There are some situations where __init__ will not get called. One example is when you unpickle objects from a pickle file, they will get allocated (__new__) but not initialised (__init__).


回答 4

只是想添加一个关于定义vs 的意图(与行为相反)的词__new____init__

当我试图理解定义类工厂的最佳方法时,我遇到了这个问题。我意识到,在__new__概念上与之不同的一种方式__init__是,这样的好处__new__恰恰是问题中所陈述的事实:

因此__new__方法的唯一好处是实例变量将从一个空字符串开始,而不是NULL。但是为什么这会有用呢,因为如果我们要确保实例变量被初始化为某个默认值,那么我们可以在__init__方法中做到这一点?

考虑到上述情况,当实例实际上是类本身时,我们关心实例变量的初始值。因此,如果我们在运行时动态创建一个类对象,并且需要定义/控制一些有关正在创建的类的后续实例的特殊操作,则可以在__new__元类的方法中定义这些条件/属性。

我一直对此感到困惑,直到我真正考虑到该概念的应用,而不仅仅是其含义。这是一个希望可以使区别清楚的示例:

a = Shape(sides=3, base=2, height=12)
b = Shape(sides=4, length=2)
print(a.area())
print(b.area())

# I want `a` and `b` to be an instances of either of 'Square' or 'Triangle'
# depending on number of sides and also the `.area()` method to do the right
# thing. How do I do that without creating a Shape class with all the
# methods having a bunch of `if`s ? Here is one possibility

class Shape:
    def __new__(cls, sides, *args, **kwargs):
        if sides == 3:
            return Triangle(*args, **kwargs)
        else:
            return Square(*args, **kwargs)

class Triangle:
    def __init__(self, base, height):
        self.base = base
        self.height = height

    def area(self):
        return (self.base * self.height) / 2

class Square:
    def __init__(self, length):
        self.length = length

    def area(self):
        return self.length*self.length

请注意,这只是一个示例。有多种方法可以获取解决方案,而无需借助上述的类工厂方法,即使我们确实选择以这种方式来实现该解决方案,为简洁起见也有一些注意事项(例如,明确声明元类) )

如果您要创建常规类(又称为非元类),那么__new__除非真正有特殊意义,例如ncoghlan答案中的可变与不可变方案(实际上是定义概念的更具体示例),否则这没有什么意义通过创建的类/类型的初始值/属性,__new__然后通过进行初始化__init__

Just want to add a word about the intent (as opposed to the behavior) of defining __new__ versus __init__.

I came across this question (among others) when I was trying to understand the best way to define a class factory. I realized that one of the ways in which __new__ is conceptually different from __init__ is the fact that the benefit of __new__ is exactly what was stated in the question:

So the only benefit of the __new__ method is that the instance variable will start out as an empty string, as opposed to NULL. But why is this ever useful, since if we cared about making sure our instance variables are initialized to some default value, we could have just done that in the __init__ method?

Considering the stated scenario, we care about the initial values of the instance variables when the instance is in reality a class itself. So, if we are dynamically creating a class object at runtime and we need to define/control something special about the subsequent instances of this class being created, we would define these conditions/properties in a __new__ method of a metaclass.

I was confused about this until I actually thought about the application of the concept rather than just the meaning of it. Here’s an example that would hopefully make the difference clear:

a = Shape(sides=3, base=2, height=12)
b = Shape(sides=4, length=2)
print(a.area())
print(b.area())

# I want `a` and `b` to be an instances of either of 'Square' or 'Triangle'
# depending on number of sides and also the `.area()` method to do the right
# thing. How do I do that without creating a Shape class with all the
# methods having a bunch of `if`s ? Here is one possibility

class Shape:
    def __new__(cls, sides, *args, **kwargs):
        if sides == 3:
            return Triangle(*args, **kwargs)
        else:
            return Square(*args, **kwargs)

class Triangle:
    def __init__(self, base, height):
        self.base = base
        self.height = height

    def area(self):
        return (self.base * self.height) / 2

class Square:
    def __init__(self, length):
        self.length = length

    def area(self):
        return self.length*self.length

Note this is just an demonstartive example. There are multiple ways to get a solution without resorting to a class factory approach like above and even if we do choose to implelent the solution in this manner, there are a little caveats left out for sake of brevity (for instance, declaring the metaclass explicitly)

If you are creating a regular class (a.k.a a non-metaclass), then __new__ doesn’t really make sense unless it is special case like the mutable versus immutable scenario in ncoghlan’s answer answer (which is essentially a more specific example of the concept of defining the initial values/properties of the class/type being created via __new__ to be then initialized via __init__).


致命错误:Python.h:没有这样的文件或目录

问题:致命错误:Python.h:没有这样的文件或目录

我正在尝试使用C扩展文件构建共享库,但首先我必须使用以下命令生成输出文件:

gcc -Wall utilsmodule.c -o Utilc

执行命令后,我得到以下错误消息:

utilsmodule.c:1:20:致命错误:Python.h:没有此类文件或目录编译终止。

我已经尝试了所有建议的解决方案,但是仍然存在该问题。我没有问题Python.h。我设法在机器上找到该文件。

I am trying to build a shared library using a C extension file but first I have to generate the output file using the command below:

gcc -Wall utilsmodule.c -o Utilc

After executing the command, I get this error message:

utilsmodule.c:1:20: fatal error: Python.h: No such file or directory compilation terminated.

I have tried all the suggested solutions over the internet but the problem still exists. I have no problem with Python.h. I managed to locate the file on my machine.


回答 0

看来您尚未正确安装python dev的标头文件和静态库。使用软件包管理器在系统范围内安装它们。

对于aptUbuntu,Debian …):

sudo apt-get install python-dev   # for python2.x installs
sudo apt-get install python3-dev  # for python3.x installs

对于yumCentOS,RHEL …):

sudo yum install python-devel   # for python2.x installs
sudo yum install python3-devel   # for python3.x installs

对于dnfFedora …):

sudo dnf install python2-devel  # for python2.x installs
sudo dnf install python3-devel  # for python3.x installs

对于zypperopenSUSE …):

sudo zypper in python-devel   # for python2.x installs
sudo zypper in python3-devel  # for python3.x installs

对于apkAlpine …):

# This is a departure from the normal Alpine naming
# scheme, which uses py2- and py3- prefixes
sudo apk add python2-dev  # for python2.x installs
sudo apk add python3-dev  # for python3.x installs

对于apt-cygCygwin …):

apt-cyg install python-devel   # for python2.x installs
apt-cyg install python3-devel  # for python3.x installs

Looks like you haven’t properly installed the header files and static libraries for python dev. Use your package manager to install them system-wide.

For apt (Ubuntu, Debian…):

sudo apt-get install python-dev   # for python2.x installs
sudo apt-get install python3-dev  # for python3.x installs

For yum (CentOS, RHEL…):

sudo yum install python-devel   # for python2.x installs
sudo yum install python3-devel   # for python3.x installs

For dnf (Fedora…):

sudo dnf install python2-devel  # for python2.x installs
sudo dnf install python3-devel  # for python3.x installs

For zypper (openSUSE…):

sudo zypper in python-devel   # for python2.x installs
sudo zypper in python3-devel  # for python3.x installs

For apk (Alpine…):

# This is a departure from the normal Alpine naming
# scheme, which uses py2- and py3- prefixes
sudo apk add python2-dev  # for python2.x installs
sudo apk add python3-dev  # for python3.x installs

For apt-cyg (Cygwin…):

apt-cyg install python-devel   # for python2.x installs
apt-cyg install python3-devel  # for python3.x installs

回答 1

在Ubuntu上,我正在运行Python 3,必须安装

sudo apt-get install python3-dev

如果要使用未链接到python3的Python版本,请安装关联的python3.x-dev软件包。例如:

sudo apt-get install python3.5-dev

On Ubuntu, I was running Python 3 and I had to install

sudo apt-get install python3-dev

If you want to use a version of Python that is not linked to python3, install the associated python3.x-dev package. For example:

sudo apt-get install python3.5-dev

回答 2

特别是对于Python 3.7Ubuntu,我需要

sudo apt install libpython3.7-dev

。我认为在某些时候名称已从此更改pythonm.n-dev

对于Python 3.6,类似地:

sudo apt install libpython3.6-dev

For Python 3.7 and Ubuntu in particular, I needed

sudo apt install libpython3.7-dev

. I think at some point names were changed from pythonm.n-dev to this.


回答 3

您必须做两件事。

为Debian / Ubuntu / Mint安装适用于Python的开发包,可通过以下命令完成:

sudo apt-get install python-dev

第二件事是,默认情况下,包含文件不在包含路径中,Python库也不与可执行文件链接。您需要添加这些标志(相应地替换Python的版本):

-I/usr/include/python2.7 -lpython2.7 

换句话说,您的编译命令应为:

gcc -Wall -I/usr/include/python2.7 -lpython2.7  utilsmodule.c -o Utilc 

Two things you have to do.

Install development package for Python, in case of Debian/Ubuntu/Mint it’s done with command:

sudo apt-get install python-dev

Second thing is that include files are not by default in the include path, nor is Python library linked with executable by default. You need to add these flags (replace Python’s version accordingly):

-I/usr/include/python2.7 -lpython2.7 

In other words your compile command ought to be:

gcc -Wall -I/usr/include/python2.7 -lpython2.7  utilsmodule.c -o Utilc 

回答 4

如果您使用的是Raspberry Pi:

sudo apt-get install python-dev

If you are using a Raspberry Pi:

sudo apt-get install python-dev

回答 5

在Fedora上针对Python 2运行它:

sudo dnf install python2-devel

而对于Python 3:

sudo dnf install python3-devel

on Fedora run this for Python 2:

sudo dnf install python2-devel

and for Python 3:

sudo dnf install python3-devel

回答 6

如果要使用tox在多个版本的Python上运行测试,则可能需要为要测试的每个Python版本安装Python开发库。

sudo apt-get install python2.6-dev 
sudo apt-get install python2.7-dev 
etc.

If you are using tox to run tests on multiple versions of Python, you may need to install the Python dev libraries for each version of Python you are testing on.

sudo apt-get install python2.6-dev 
sudo apt-get install python2.7-dev 
etc.

回答 7

Cygwin的解决方案

您需要安装软件包python2-develpython3-devel,具体取决于您使用的Python版本。

您可以使用Cygwin.com上的32位64位 setup.exe(取决于您的安装)快速安装它。

示例(setup.exe如果需要,可以修改的文件名和Python的主要版本):

$ setup.exe -q --packages=python3-devel

您也可以在其他答案中查看我的其他答案,以从命令行安装Cygwin的软件包。

Solution for Cygwin

You need to install the package python2-devel or python3-devel, depending on the Python version you’re using.

You can quickly install it using the 32-bit or 64-bit setup.exe (depending on your installation) from Cygwin.com.

Example (modify setup.exe‘s filename and Python’s major version if you need):

$ setup.exe -q --packages=python3-devel

You can also check my other answer for a few more options to install Cygwin’s packages from the command-line.


回答 8

在AWS API(centOS)中

yum install python27-devel

In AWS API (centOS) its

yum install python27-devel

回答 9

对我来说,将其更改为有效:

#include <python2.7/Python.h>

我找到了文件/usr/include/python2.7/Python.h,并且由于/usr/include已经在include路径中,因此python2.7/Python.h应该足够了。

您也可以从命令行添加包含路径- gcc -I/usr/lib/python2.7(感谢@ erm3nda)。

For me, changing it to this worked:

#include <python2.7/Python.h>

I found the file /usr/include/python2.7/Python.h, and since /usr/include is already in the include path, then python2.7/Python.h should be sufficient.

You could also add the include path from command line instead – gcc -I/usr/lib/python2.7 (thanks @erm3nda).


回答 10

确保您的操作系统随附Python开发文件。

您不应该对库进行硬编码并包含路径。而是使用pkg-config,它将为您的特定系统输出正确的选项:

$ pkg-config --cflags --libs python2 -I/usr/include/python2.7 -lpython2.7

您可以将其添加到您的gcc行:

gcc -Wall utilsmodule.c -o Utilc $(pkg-config --cflags --libs python2) 

Make sure that the Python dev files come with your OS.

You should not hard code the library and include paths. Instead, use pkg-config, which will output the correct options for your specific system:

$ pkg-config --cflags --libs python2 -I/usr/include/python2.7 -lpython2.7

You may add it to your gcc line:

gcc -Wall utilsmodule.c -o Utilc $(pkg-config --cflags --libs python2) 

回答 11

运行python34的AWS EC2安装:

sudo yum install python34-devel

AWS EC2 install running python34:

sudo yum install python34-devel


回答 12

就我而言,在Ubuntu中修复该问题的是安装软件包libpython-all-dev(或者libpython3-all-dev如果您使用Python 3)。

In my case, what fixed it in Ubuntu was to install the packages libpython-all-dev (or libpython3-all-dev if you use Python 3).


回答 13

如果您使用带有3.6 python的virtualenv(现在是edge),请确保安装匹配的python 3.6 dev sudo apt-get install python3.6-dev,否则执行sudo python3-dev将安装python dev 3.3.3-1,这将无法解决问题。

If you use a virtualenv with a 3.6 python (edge right now), be sure to install the matching python 3.6 dev sudo apt-get install python3.6-dev, otherwise executing sudo python3-dev will install the python dev 3.3.3-1, which won’t solve the issue.


回答 14

情况不一样,但对我也适用,现在我可以在Python3.5中使用SWIG了:

我正在尝试编译:

gcc -fPIC -c existe.c existe_wrap.c -I /usr/include/python3.5m/

使用Python 2.7可以正常工作,而不能用于我的3.5版本:

existe_wrap.c:147:21:致命错误:Python.h:没有存档或目录编译终止。

在我的Ubuntu 16.04安装中运行后:

sudo apt-get install python3-dev  # for python3.x installs

现在,我可以毫无问题地编译Python3.5了:

gcc -fPIC -c existe.c existe_wrap.c -I /usr/include/python3.5m/

It’s not the same situation, but it also works for me and now I can use SWIG with Python3.5:

I was trying to compile:

gcc -fPIC -c existe.c existe_wrap.c -I /usr/include/python3.5m/

With Python 2.7 works fine, not with my version 3.5:

existe_wrap.c:147:21: fatal error: Python.h: No existe el archivo o el directorio compilation terminated.

After run in my Ubuntu 16.04 installation:

sudo apt-get install python3-dev  # for python3.x installs

Now I can compile without problems Python3.5:

gcc -fPIC -c existe.c existe_wrap.c -I /usr/include/python3.5m/

回答 15

我在ubuntu中安装coolprop时也遇到了此错误。

对于带有python 3.6的ubuntu 16.04

sudo apt-get install python3.6-dev

如果这不起作用,请尝试安装/更新gcclib。

sudo apt-get install gcc

I also encountered this error when I was installing coolprop in ubuntu.

For ubuntu 16.04 with python 3.6

sudo apt-get install python3.6-dev

If ever this doesn’t work try installing/updating gcc lib.

sudo apt-get install gcc

回答 16

尝试apt文件。很难记住丢失文件所在的软件包名称。它是通用的,对任何软件包文件都有用。

例如:

root@ubuntu234:~/auto# apt-file search --regexp '/Python.h$'
pypy-dev: /usr/lib/pypy/include/Python.h
python2.7-dbg: /usr/include/python2.7_d/Python.h
python2.7-dev: /usr/include/python2.7/Python.h
python3.2-dbg: /usr/include/python3.2dmu/Python.h
python3.2-dev: /usr/include/python3.2mu/Python.h
root@ubuntu234:~/auto# 

现在,您可以对要选择的专家进行猜测。

try apt-file. It is difficult to remember the package name where the missing file resides. It is generic and useful for any package files.

For example:

root@ubuntu234:~/auto# apt-file search --regexp '/Python.h$'
pypy-dev: /usr/lib/pypy/include/Python.h
python2.7-dbg: /usr/include/python2.7_d/Python.h
python2.7-dev: /usr/include/python2.7/Python.h
python3.2-dbg: /usr/include/python3.2dmu/Python.h
python3.2-dev: /usr/include/python3.2mu/Python.h
root@ubuntu234:~/auto# 

Now you can make an expert guess as to which one to choose from.


回答 17

我设法解决了这个问题,并在一个命令中生成了.so文件

gcc -shared -o UtilcS.so
-fPIC -I/usr/include/python2.7 -lpython2.7  utilsmodule.c

I managed to solve this issue and generate the .so file in one command

gcc -shared -o UtilcS.so
-fPIC -I/usr/include/python2.7 -lpython2.7  utilsmodule.c

回答 18

对于OpenSuse同志:

sudo zypper install python3-devel

For the OpenSuse comrades out there:

sudo zypper install python3-devel

回答 19

对于CentOS 7:

sudo yum install python36u-devel

我按照此处的说明在多个VM上安装python3.6:https ://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming- 在centos-7上运行 ,然后能够构建mod_wsgi并使其与python3.6 virtualenv一起使用

For CentOS 7:

sudo yum install python36u-devel

I followed the instructions here for installing python3.6 on several VMs: https://www.digitalocean.com/community/tutorials/how-to-install-python-3-and-set-up-a-local-programming-environment-on-centos-7 and was then able to build mod_wsgi and get it working with a python3.6 virtualenv


回答 20

如果您在Amazon Linux上使用Python 3.6(基于RHEL,但此处给出的RHEL答案无效):

sudo yum install python36-devel

If you’re using Python 3.6 on Amazon Linux (based on RHEL, but the RHEL answers given here didn’t work):

sudo yum install python36-devel

回答 21

当我尝试使用Python3.6在CentOS 7上安装ctds时发生此错误。我做了这里提到的所有技巧,包括yum install python34-devel。在Python.h中发现了问题/usr/include/python3.4m but not in /usr/include/python3.6m。我试图--global-option指向包含dir(pip3.6 install --global-option=build_ext --global-option="--include-dirs=/usr/include/python3.4m" ctds)的位置。导致在lpython3.6m链接ctds时找不到。

最后,有效的方法是修复Python3.6的开发环境,需要使用include和libs进行更正。

yum -y install https://dl.iuscommunity.org/pub/ius/stable/CentOS/7/x86_64/python36u-libs-3.6.3-1.ius.centos7.x86_64.rpm

Python.h必须位于gcc的包含路径中。无论使用哪个版本的python(例如,如果版本为3.6,则/usr/include/python3.6m/Python.h通常都应使用该版本)。

This error occurred when I attempted to install ctds on CentOS 7 with Python3.6. I did all the tricks mentioned here including yum install python34-devel. The problem was Python.h was found in /usr/include/python3.4m but not in /usr/include/python3.6m. I tried to use --global-option to point to include dir (pip3.6 install --global-option=build_ext --global-option="--include-dirs=/usr/include/python3.4m" ctds). This resulted in a lpython3.6m not found when linking ctds.

Finally what worked was fixing the development environment for Python3.6 needs to correct with the include and libs.

yum -y install https://dl.iuscommunity.org/pub/ius/stable/CentOS/7/x86_64/python36u-libs-3.6.3-1.ius.centos7.x86_64.rpm

Python.h needs to be in your include path for gcc. Whichever version of python is used, for example if it’s 3.6, then it should be in /usr/include/python3.6m/Python.h typically.


回答 22

当然,python-dev还是libpython-all-devapt)的第一件事install,但是,如果这对我的情况没有帮助,我建议您通过和安装外部功能接口软件包。sudo apt-get install libffi-devsudo pip install cffi

如果您看到错误信息as / from,这应该会有所帮助c/_cffi_backend.c:2:20: fatal error: Python.h: No such file or directory

Sure python-dev or libpython-all-dev are the first thing to (apt )install, but if that doesn’t help as was my case, I advice you to install the foreign Function Interface packages by sudo apt-get install libffi-dev and sudo pip install cffi.

This should help out especially if you see the error as/from c/_cffi_backend.c:2:20: fatal error: Python.h: No such file or directory.


回答 23

当您尝试删除python3.5和安装时,它经常出现python3.6

因此,当使用python3(which python3 -V=> python3.6)安装某些软件包时,所需的python3.5标头将出现此错误。

通过安装python3.6-dev模块解决。

It often appear when you trying to remove python3.5 and install python3.6.

So when using python3 (which python3 -V => python3.6) to install some packages required python3.5 header will appear this error.

Resolve by install python3.6-dev module.


回答 24

  1. 如果操作系统随附的Python不附带Python开发文件,则必须在其上安装Python开发文件。关于这个问题的许多答案显示了在不同系统上可以实现的无数种方法。

  2. 您这样做时,问题是告诉编译器它们的位置以及如何针对它们进行编译。Python附带了一个名为的程序python-config。对于编译,您需要--includes输出,并且需要将程序链接到Python库(将Python嵌入程序中)到--ldflags输出。例:

    gcc -c mypythonprogram.c $(python3-config --includes)
    gcc -o program mypythonprogram.o $(python3-config --ldflags)

python-config程序可以以Python版本命名-例如在Debian,Ubuntu上,它们可以命名为python3-configpython3.6-config

  1. You must install the Python development files on your operating system if the Python provided with your operating system does not come with them. The many answers on this question show the myriad ways this can be achieved on different systems.

  2. When you have done so, the problem is telling the compiler where they’re located and how to compile against them. Python comes with a program called python-config. For compilation, you need the --includes output and for linking a program against the Python library (embedding Python into your program) the --ldflags output. Example:

    gcc -c mypythonprogram.c $(python3-config --includes)
    gcc -o program mypythonprogram.o $(python3-config --ldflags)
    

The python-config program can be named after the Python versions – on Debian, Ubuntu for example these can be named python3-config or python3.6-config.


回答 25

有时即使安装了python-dev之后,错误仍然存​​在,如果没有’gcc’,请检查错误。

首先按照https://stackoverflow.com/a/21530768/8687063中的说明进行下载,然后安装gcc

对于apt(Ubuntu,Debian …):

sudo apt-get install gcc

对于百胜(CentOS,RHEL …):

sudo yum install gcc

对于dnf(Fedora …):

sudo dnf install gcc

对于zypper(openSUSE …):

sudo zypper in gcc

对于apk(高山…):

sudo apk gcc

Sometimes even after installing python-dev the error persists, Check for the error if it is ‘gcc’ missing.

First download as stated in https://stackoverflow.com/a/21530768/8687063, then install gcc

For apt (Ubuntu, Debian…):

sudo apt-get install gcc

For yum (CentOS, RHEL…):

sudo yum install gcc

For dnf (Fedora…):

sudo dnf install gcc

For zypper (openSUSE…):

sudo zypper in gcc

For apk (Alpine…):

sudo apk gcc

回答 26

这意味着它Python.h不在编译器的默认包含路径中。您在系统范围内还是在本地安装了它?您的操作系统是什么?

您可以使用该-I<path>标志指定编译器应在其中查找标头的其他目录。您可能需要跟进,-L<path>以便gcc可以找到要使用链接的库-l<name>

This means that Python.h isn’t in your compiler’s default include paths. Have you installed it system-wide or locally? What’s your OS?

You could use the -I<path> flag to specify an additional directory where your compiler should look for headers. You will probably have to follow up with -L<path> so that gcc can find the library you’ll be linking with using -l<name>.