2011-09-29 3 views
1

Есть ли способ взломать функцию Python (def) для возврата результатов по ссылке даже для неизменяемых типов?Python: переменные по ссылкам (hack)

приложение предложение (своп в качестве подпрограммы):
def swap(a, b):
.....a,b = b,a

Примечание:
def swap(a, b):
.....return b,a

работает как функция, не ответ на вопрос!

Например, существует функция random.shuffle (a), которая работает на месте. Моя идея - вызвать функцию, написанную на языке Fortran/C++, и вызвать их через Python. Он работает, но имеет и недостатки.
примечание:
И «lambda», и «def» (как функция) имеют следующую проблему: a, b = swap(a, b), которая требует ухода за порядком переменных. В моем предложении (если это было возможно) подпрограмма используется как: swap(a, b), поэтому нет необходимости заботиться о порядке переменной.

+0

Я не знаю, если я получил это право, но вы, кажется, ищет 'функции lambda'. Можете ли вы дать более подробное объяснение и пример? – heltonbiker

+1

Нет, и вы не хотите этого точно. – JBernardo

+1

И «лямбда», и «def» (как функция) имеют следующую проблему: 'a, b = swap (a, b)', которая требует осторожности порядка переменных. В моем предложении (если это было возможно) подпрограмма используется как: 'swap (a, b)', поэтому нет необходимости заботиться о порядке переменной. – Developer

ответ

4

Все имена в Python являются ссылками. И нет, нет никаких «выходных» ссылок (например, в смысле C++). Вам нужно передать измененный объект, а затем вы можете его изменить в функции. Но опять же, возвращение нового значения (ов) должно быть предпочтительным способом.

+1

См. Мой комментарий ниже вопроса, который демонстрирует преимущества моего предложения. – Developer

+1

@ Разработчик: Нет, нет никаких преимуществ, и не только потому, что это невозможно. Это не идиоматический код. Идиоматический обмен - это 'a, b = b, a'. –

+0

Обратите внимание, что своп является лишь примером для объяснения идеи. – Developer

3

Нет, таких вещей не существует, потому что вы получаете данный объект в качестве ссылки, но если вы его повторно назначите, он не будет изменен.

В этом случае вам придется работать с изменяемым контейнером (список, dict, объект с атрибутами).

2

В python нет способа передать «указатель записи». Вы можете передать объект и имя (поэтому вызываемый может использовать, например, setattr), или вы можете передать список и индекс. Нет такого понятия, как контекстный «адрес изменяемой ячейки» ... есть только имена или индексы, которые, однако, также нуждаются в контексте (какое пространство имен, какой массив).

В общем случае, если вам действительно нужно передать указатель записи, решение в Python должно передать функцию «setter», которая может использоваться вызываемым пользователем для установки значения.

Например:

def foo(setter): 
    setter(42) 

def bar(): 
    x = [1,2,3,4] 

    def setFirst(value): 
     x[0] = value 

    foo(setFirst) 

    print x[0] # --> 42 
Смежные вопросы