Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:模拟变量的C风格传递引用_Python_C_Reference - Fatal编程技术网

Python:模拟变量的C风格传递引用

Python:模拟变量的C风格传递引用,python,c,reference,Python,C,Reference,我有一个类似C语言的框架。现在我正在编写这个框架,该语言正被Python所取代 我需要为以下代码构造找到合适的Python替代品: SomeFunction(&arg1) 这是一个C风格的传递引用,因此可以在函数调用中更改变量 我的想法是: 只需返回值,如v=SomeFunction(arg1) 不是很好,因为我的泛型函数可以有很多参数,比如SomeFunction(1,2、'qqq'、'vvv'、…等等) 我想让用户能够获得她想要的价值 返回所有参数的集合,无论它们是否已更改,例如:

我有一个类似C语言的框架。现在我正在编写这个框架,该语言正被Python所取代

我需要为以下代码构造找到合适的Python替代品:

SomeFunction(&arg1)
这是一个C风格的传递引用,因此可以在函数调用中更改变量

我的想法是:

  • 只需返回值,如
    v=SomeFunction(arg1)

    不是很好,因为我的泛型函数可以有很多参数,比如
    SomeFunction(1,2、'qqq'、'vvv'、…等等)
    我想让用户能够获得她想要的价值

  • 返回所有参数的集合,无论它们是否已更改,例如:
    resulting\u list=SomeFunction(1,2、'qqq'、'vvvv'、…等等)
    interest\u value=resulting\u list[3]

    这可以通过给值命名并返回dictionary
    interest\u value=resulted\u list['magic\u value1']

    这不好,因为我们有这样的结构

    DoALotOfStaff( [SomeFunction1(1,2,3,&arg1,'qq',val2),
                    SomeFunction2(1,&arg2,v1),
                    AnotherFunction(),
                    ...
                   ], flags1, my_var,... )
    
    我不想给用户加载变量列表,以及她(用户)应该知道的名称或索引。这类参考资料在这里非常有用

  • 最终响应

    我用自己的想法整理了所有的答案,并且能够得出答案。它起作用了

  • 用法

    SomeFunction(1,12, get.interesting_value)
    AnotherFunction(1, get.the_val, 'qq')
    
  • 解释

    get.
    前面的任何内容都是一种引用,其值将由函数填充。不需要在前面定义值

    限制-目前我只支持数字和字符串,但从我的用例来看,这些已经足够了

  • 实施

    • 编写了一个Getter类,它重写getattribute,并根据需要生成任何变量

    • 所有新创建的变量都有指向其容器Getter和support方法集(self,value)的指针

    • 调用set()时,它会检查值是int还是string,并相应地创建从int或str继承的对象,但添加了相同的set()方法。使用这个新对象,我们将替换Getter容器中的实例

  • 谢谢大家。我将把引导我前进的回答标记为“回答”,但你们所有人都以某种方式帮助了我

    Python就是这样工作的:

    def func(arg):
      arg += ['bar']
    
    arg = ['foo']
    func(arg)
    print arg
    
    在这里,对
    arg
    的更改会自动传播回调用者

    要使其正常工作,必须小心地就地修改参数,而不是将其重新绑定到新对象。考虑以下事项:

    def func(arg):
      arg = arg + ['bar']
    
    arg = ['foo']
    func(arg)
    print arg
    

    在这里,
    func
    重新绑定
    arg
    以引用一个全新的列表,而调用方的
    arg
    保持不变。

    我想说,您最好、最干净的赌注是构造一个包含要传递和/或修改的值的对象-这个对象可以传递(并将通过引用自动传递),在中作为单个参数,可以修改成员以返回新值

    这将极大地简化代码,您可以干净地处理可选参数、默认值等

    >>> class C:
    ...    def __init__(self):
    ...        self.a = 1
    ...        self.b = 2
    ... 
    >>> c=C
    >>> def f(o):
    ...    o.a = 23
    ... 
    >>> f(c)
    >>> c
    <class __main__.C at 0x7f6952c013f8>
    >>> c.a
    23
    >>> 
    
    >>C类:
    ...    定义初始化(自):
    ...        self.a=1
    ...        self.b=2
    ... 
    >>>c=c
    >>>def f(o):
    ...    o、 a=23
    ... 
    >>>f(c)
    >>>c
    >>>c.a
    23
    >>> 
    
    注 我相信您可以扩展这个想法,使其具有一个参数类,该类参数将不可变和可变的数据携带到函数中,使用固定的成员名称,并存储实际传递的参数名称,然后在返回时将可变值映射回调用方参数名称。然后,可以将此技术包装到装饰器中


    我不得不说,与将现有代码重新分解为更面向对象的设计相比,这听起来需要做很多工作。

    Python没有内置这种东西。您可以创建自己的类来提供这种行为,但它只支持稍微笨拙的语法,调用方在调用函数之前构造该类的实例(相当于C中的指针)。这可能不值得。相反,我会返回一个“”(查找)——我不确定其他方法是否真的更好,其中一些更复杂。

    这里有一个主要的不一致性。您针对建议的解决方案描述的缺点与良好设计的微妙规则有关,因此您的问题变得无效。整个问题在于,您的函数违反了和其他相关的准则(函数的参数不应超过2-3个,等等)。这里真的没有明智的妥协:

    • 要么您接受其中一个建议的解决方案(即关于您自己的包装器,要么关于命名元组的使用),不要关注好的设计细节(因为您的整个设计目前都不好)

    • 或者你修改设计。然后,您当前的问题将消失,因为您将不再需要处理(示例中的函数名称-
      doalotofsuff
      本身就说明问题了)


    在python中,所有参数仅通过引用传递。:)@你们称之为“通行证”的不是C++人(和许多其他语言——他们使用术语“第一”!)的意思是“通过引用”。这就是为什么有人反对说Python“通过引用传递”的原因。因此,OP的一个问题是:您是在试图更改
    arg1
    ,以便它引用的值被函数更改,还是在试图更改它,以便它在函数调用后实际引用一个完全不同的对象?如果是后者,Python并不完全支持这一点……事实上,C也不支持这一点,但在C中,您始终可以添加另一个级别的指针间接寻址。不,Python已经不是这样工作的了。它是