python自动转换参数 我使用BooS.Python来封装一个C++类“A”,它把一个字符串作为构造函数。然后我有一个函数“fun(a&arg)”,它将对“a”的引用作为参数。我希望有一个“fun”的python包装器,如果我传递一个对python字符串的引用的变量,这个引用首先会自动转换为对“a”的引用

python自动转换参数 我使用BooS.Python来封装一个C++类“A”,它把一个字符串作为构造函数。然后我有一个函数“fun(a&arg)”,它将对“a”的引用作为参数。我希望有一个“fun”的python包装器,如果我传递一个对python字符串的引用的变量,这个引用首先会自动转换为对“a”的引用,python,c++,boost,reference,boost-python,Python,C++,Boost,Reference,Boost Python,举个例子可能会有所帮助。在python方面,我希望能够做到这一点: a = 'some string' fun(a) 然后让“a”实际上是(对)一个“a”的引用,而不是(对)原始字符串的引用。我想这样做是因为我希望能够避免将此作为 a = A('some string') fun(a) (你可能有充分的理由怀疑这是否是一个相关的储蓄,但让我们假设它对我很重要) 这样做可能吗?如果不使用boost.python,可能直接使用python-capi 注:我知道,如果我愿意 fun('some s

举个例子可能会有所帮助。在python方面,我希望能够做到这一点:

a = 'some string'
fun(a)
然后让“a”实际上是(对)一个“a”的引用,而不是(对)原始字符串的引用。我想这样做是因为我希望能够避免将此作为

a = A('some string')
fun(a)
(你可能有充分的理由怀疑这是否是一个相关的储蓄,但让我们假设它对我很重要)

这样做可能吗?如果不使用boost.python,可能直接使用python-capi

注:我知道,如果我愿意

fun('some string')
无法将对字符串的引用转换为对其他类型的引用。

要使其正常工作
fun(a)
必须修改原始
a
对象引用。
fun(a)
实际得到的是对象引用
a
的本地副本,而不是作为参数传递的原始
a
对象引用


换句话说,Python不是这样工作的,您需要将其称为
a=fun(a)
才能更改引用
a
(不是它所引用的对象)。

这是可能的,但解决方案可能依赖于Python实现

例如,在Python2.7中,模块和可用于在特定帧上修改。这也可以在Python/capi中实现,但是在Python中操作Python框架通常要容易得多

在下面的
example.py
中,
update\u locals()
函数将更新给定帧中的
locals()

导入检查
导入系统
定义强制局部变量(旧框架、新局部变量):
''在给定帧上强制一组新的局部变量。
:param old_frame:将应用局部变量的帧。
:键入旧框架:框架。
:param new_locals:What locals()应为旧_帧返回。
:键入new\u locals:dict。
.. 注意:此函数将强制将自定义跟踪函数加载到
旧框架。在跟踪函数的上下文中
(通常用于调试),帧的f_局部变量是
可修改的。在大多数执行路径中,f_局部变量是
可写但不可修改。
'''
#通过将全局跟踪功能设置为
#任何非None函数。
如果不是sys.gettrace():
sys.settrace(lambda*args,**键:无)
#自定义跟踪函数,将强制使用局部变量。
def跟踪(帧、事件、参数):
#更新帧的局部变量。
frame.f_locals.update(新_locals)
#将帧设置为使用默认跟踪,防止此跟踪
#函数在每次跟踪调用时重置局部变量。
del frame.f_跟踪
#将旧框架的跟踪函数设置为自定义跟踪。
old_frame.f_trace=跟踪
def更新_局部变量(帧,*参考):
''根据提供的引用修改帧的局部变量。
:param frame:将从中更新局部变量的帧。
:类型框架:框架。
:param refs:Iterable(旧的、新的)元组对。
:type refs:Iterable类型的对。
'''
new_locals=frame.f_locals.copy()
has_changes=False
#如果帧的本地具有提供的标识修补程序
#引用,然后使用新引用更新新的_局部变量。
对于键,请在new_locals.iteritems()中引用:
对于旧参考,参考中的新参考:
如果ref是旧的\u ref:
新的\u局部变量[键]=新的\u参考
has_changes=True
#如果新的_局部变量有更改,则将其强制到框架上。
如果有变更:
_强制局部变量(帧、新局部变量)
互动使用:

>>导入示例
>>>进口检验
>>>x=42
>>>x
42
>>>示例.更新_局部变量(inspect.currentframe(),(x,'3.14'))
>>>x
'3.14'
x
变量引用了
int(42)
对象,但是
示例.update\u locals()
函数将
x
更改为引用
str('3.14')
对象


通过修改Python的框架,下一步是在Python中对C++<代码>()/代码>进行补丁编译,构建一个实例:<代码> A/C++ >如果该参数是“代码> STR 的实例,那么委托给C++ <代码> Fun(A&)函数,并更新调用方的框架。

下面的例子,一个C++代码>垃圾邮件类型和乐趣(垃圾邮件和)//>函数被暴露在<代码>示例 Python模块。

#包括
#包括
#包括
///@简要模型类型。
类垃圾邮件
{
公众:
显式垃圾邮件(std::string str)
:str(str)
{}
无效行动()
{
std::cout>>导入示例
>>>s1=示例.Spam('abc')
>>>类型(s1)
>>>示例.乐趣(s1)
fun()->Spam::action():abc
>>>类型(s1)#s1的类型没有改变。
>>>s2=‘def’
>>>类型(s2)
>>>示例.乐趣(s2)
fun()->Spam::action():def
>>>类型(s2)#s2的类型已更改。
>>>示例。乐趣(“ghi”)
fun()->Spam::action():ghi

请注意,上面示例中的帧操纵仅修改的
fun()<代码>的调用方的框架,而不是整个堆栈。

我知道Python是这样的,如果它是纯Python的话。我的问题是,是否有一种方法在“通过C++”传递“欺骗”的时候。换句话说,C++ API是否给了我一个改变引用的方式,而不仅仅是本地副本。我猜不是……这不是我真正想要的,而是它。无论如何,(对另一个问题)这是一个很好的答案;-)@Kasperpeters:Doh。我相信我误解了引用应该更改的范围。我已经更新了我的答案(希望)回答你的问题