我正在使用CPython而且我有一个C#dll.我正在尝试使用Python for .NET来让他们说话.我不能使用IronPython,因为我需要将它集成到现有的CPython系统中.
我是Python for .NET的新手,我实际上对Python的经验很少,而且没有使用C#的经验.如果我的问题看起来很基本,请原谅我.
我正在使用Python 2.7.3,我下载了pythonnet-2.0-alpha2-clr2.0_131_py27_UCS2并将其解压缩到名为pyfornet_test的文件夹中,该文件夹还包含我正在尝试使用的dll(称为DotNet4Class.dll)
然后我运行这个:
import sys
import os
import clr
sys.path.append(r"C:\pyfornet_test")
clr.AddReference("DotNet4Class.dll")
Run Code Online (Sandbox Code Playgroud)
这给了我这个错误:
System.IO.FileNotFoundException: Unable to find assembly 'DotNet4Class.dll'.
at Python.Runtime.CLRModule.AddReference(String name) in C:\Users\Barton\Documents\Visual Studio 2008\Projects\PyShar
p\trunk\pythonnet\src\runtime\moduleobject.cs:line 375
Run Code Online (Sandbox Code Playgroud)
任何建议将不胜感激.谢谢!
我正在编写C扩展,我想让我的方法的签名可见为内省.
static PyObject* foo(PyObject *self, PyObject *args) {
/* blabla [...] */
}
PyDoc_STRVAR(
foo_doc,
"Great example function\n"
"Arguments: (timeout, flags=None)\n"
"Doc blahblah doc doc doc.");
static PyMethodDef methods[] = {
{"foo", foo, METH_VARARGS, foo_doc},
{NULL},
};
PyMODINIT_FUNC init_myexample(void) {
(void) Py_InitModule3("_myexample", methods, "a simple example module");
}
Run Code Online (Sandbox Code Playgroud)
现在,如果(在构建它之后......)我加载模块并查看它的帮助:
>>> import _myexample
>>> help(_myexample)
Run Code Online (Sandbox Code Playgroud)
我会得到:
Help on module _myexample:
NAME
_myexample - a simple example module
FILE
/path/to/module/_myexample.so
FUNCTIONS
foo(...)
Great example function
Arguments: (timeout, flags=None)
Doc blahblah doc doc …Run Code Online (Sandbox Code Playgroud) __slots__在Python中实现?__slots__在C中定义Python类时如何获得行为PyTypeObject?Python C-API中的标准约定是
函数不会从输入参数(即对象)中窃取引用
返回值和输出参数(即对象)拥有引用
Python C-API中的大多数函数都遵循此约定.但是,也有一些例外.我遇到过以下情况:
从输入参数中窃取引用的函数
PyModule_AddObject
Run Code Online (Sandbox Code Playgroud)
具有返回值的函数或借用引用的输出参数
PyErr_Occurred
PyTuple_GetItem
PyTuple_GETITEM
PyDict_GetItem
PyDict_GetItemString
PyDict_Next
Run Code Online (Sandbox Code Playgroud)
在任何地方都有这样的功能的完整列表吗?编写Python扩展模块时,这样的列表将是一个有用的参考.
我在(自制的)基于C的python扩展中运行一些计算量很大的模拟.偶尔我会弄错,想终止模拟.但是,Ctrl-C似乎没有任何效果(除了打印^C到屏幕,所以我必须使用kill或系统监视器终止进程.
据我所知,python只是等待C扩展完成,并且在此期间并没有真正与它通信.
有没有办法让这项工作?
如果我做的事情
>>> x = int(1,2,3,4,5)
Run Code Online (Sandbox Code Playgroud)
我立即得到一个致命的错误(如果它是在一个预先编写的脚本中就会结束程序执行)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: int() takes at most 2 arguments (5 given)
Run Code Online (Sandbox Code Playgroud)
并且x仍未定义:
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Run Code Online (Sandbox Code Playgroud)
我将如何在Python的C API中实现它?我找到了一些文档,但我不确定我是否知道如何正确使用它.
这是我一直在尝试的:
打印:
if(something) {
PyErr_SetString(PyExc_TypeError, "Oh no!");
PyErr_Print();
}
Run Code Online (Sandbox Code Playgroud)
遗憾的是,这只会打印异常并继续执行程序.另外,如果我理解正确 - PyErr_Print()从某种队列中删除异常,因此Python认为它已被处理.这就是它的样子:
>>> import awesomemod
>>> x = awesomemod.thing()
TypeError: Oh no!
>>> x # x is …Run Code Online (Sandbox Code Playgroud)如何PyObject从C++ 获取a的引用计数?
有功能Py_INCREF,Py_DECREF并增加/减少它,但我没有找到任何返回对象的引用计数的函数.
我需要它用于调试目的.
我正在尝试调试Python 2.7的C扩展.我使用python2.7调试版本.我建立我的项目,setuptools我setup.py有这样的台词:
ext_modules=[Extension("my.extension",
["my/_extension.c"])]
Run Code Online (Sandbox Code Playgroud)
当我python setup.py install因某种原因调用扩展时编译为带_d后缀的文件,之后,在Python中,我不能这样做import my.extension,我只能这样做import my.extension_d.而我得到的是:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "build/bdist.linux-x86_64/egg/my/extension_d.py", line 7, in <module>
File "build/bdist.linux-x86_64/egg/my/extension_d.py", line 6, in __bootstrap__
ImportError: dynamic module does not define init function (initextension_d)
Run Code Online (Sandbox Code Playgroud)
当然我的扩展没有initextension_d,它只有initextension功能.
这非常不方便,因为我必须更改一些代码并将此_d后缀添加到导入和其他内容中.
是否可以关闭此后缀的前置?或者如何以其他方式处理该问题?也许有一些"官方"的方式?
我使用的是Ubuntu Linux.
我有一个Python扩展模块,它创建一个元组作为另一个对象的属性,并设置元组中的项目.每当我在Python中执行此模块时,我都会收到错误SystemError: bad argument to internal function
在阅读了文档PyTuple并调试我的程序几个小时后,我仍然无法弄清楚到底是怎么回事.通过调试器运行我的程序表明问题发生在Python解释器内的库调用中.所以,最后,我查看了Python源代码,最后我意识到了这个问题.该PyTuple_SetItem函数有一个我不知道的有趣限制,并且无法找到明确记录.
这是Python源代码中的重要功能(为清晰起见编辑):
int PyTuple_SetItem(register PyObject *op, register Py_ssize_t i, PyObject *newitem)
{
.....
if (!PyTuple_Check(op) || op->ob_refcnt != 1) {
Py_XDECREF(newitem);
PyErr_BadInternalCall();
return -1;
}
.....
}
Run Code Online (Sandbox Code Playgroud)
这里重要的一行是条件op-> ob_refcnt!= 1.所以这就是问题所在:PyTuple_SetItem除非元组的ref-count为1,否则你甚至无法调用.看起来这里的想法是你永远不应该使用,PyTuple_SetItem除非你创建一个元组后使用PyTuple_New().我想这是有道理的,因为毕竟Tuples应该是不可变的,所以这个限制有助于保持你的C代码更符合Python类型系统的抽象.
但是,我无法在任何地方找到此限制.相关文档似乎在这里和这里,两者都没有指定这个限制.文档基本上说当你调用时PyTuple_New(X),元组中的所有项都被初始化为NULL.由于NULL不是一个有效的Python值,因此扩展模块程序员可以确保在将Tuple返回到解释器之前,使用正确的Python值填充元组中的所有插槽.但是,当Tuple对象的ref计数为1时,它并没有说任何必须这样做.
所以现在,问题是我基本上把自己写进了一个角落,因为我不知道这个(未记录的?)限制PyTuple_SetItem.我的代码,因为它是非常不方便将项目插入元组,直到这样的结构后的元组本身也成为另一个对象的属性.因此,当需要填写元组中的项时,元组已经具有更高的引用计数.
我可能不得不重构我的代码,但我认真考虑暂时将元组上的引用计数设置为1,插入项目,然后恢复原始引用计数.当然,这是一个可怕的黑客,我知道,而不是任何永久的解决方案.无论如何,我想知道关于元组的引用计数的要求是否记录在任何地方.它只是CPython的实现细节,还是API用户可以依赖的预期行为?
搞乱Python.h时我遇到了这个错误:
AttributeError: 'module' object has no attribute 'argv'
Run Code Online (Sandbox Code Playgroud)
C++代码:
#include "stdafx.h"
#include "C:/Python27/include/Python.h"
#include <iostream>
using namespace std;
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys\nprint sys.argv[0]");
}
Run Code Online (Sandbox Code Playgroud)
在Python中是:
import sys
print sys.argv[0]
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
python ×10
python-c-api ×10
c ×3
c++ ×2
.net ×1
api ×1
descriptor ×1
interop ×1
linux ×1
python-3.x ×1
python.net ×1
slots ×1
tuples ×1