Эмуляция поведения передачи значением в Python

<?php
    $total = 0;
    for($i = 1; $i <= 5; $i++) {
        $total = $total + $i;
        echo  $total."<br>";
    }
?>

Вы можете достичь этого, добавив значение $ i с $ total value

58
задан Boris Gorelik 13 May 2009 в 05:10
поделиться

5 ответов

Нет питонического способа сделать это.

Python предоставляет очень мало средств для принудительного таких вещей, как личные данные или данные только для чтения. Философия питона состоит в том, что «мы все взрослые по согласию»: в данном случае это означает, что «функция не должна изменять данные» является частью спецификации, но не применяется в коде.


Если вы хотите сделать копию данных, самое близкое, что вы можете найти, - это ваше решение. Но copy.deepcopy , помимо того, что он неэффективен, также имеет предостережения , например :

Поскольку глубокая копия копирует все, она может копировать слишком много, например, структуры административных данных, которые должны быть общими даже между копиями.

[...]

Этот модуль не копирует такие типы, как модуль, метод, трассировка стека, фрейм стека, файл, сокет, окно, массив или любые подобные типы.

Поэтому я бы рекомендовал его только в том случае, если вы знаете, что имеете дело со встроенными типами Python или вашими собственными объектами (где вы можете настроить поведение копирования, определив __ copy __ / __ deepcopy__ специальные методы, нет необходимости определять собственный метод clone () ).

32
ответ дан 24 November 2019 в 19:05
поделиться

Вы можете создать декоратор и поместить в него поведение клонирования.

>>> def passbyval(func):
def new(*args):
    cargs = [deepcopy(arg) for arg in args]
    return func(*cargs)
return new

>>> @passbyval
def myfunc(a):
    print a

>>> myfunc(20)
20

Это не самый надежный способ, и он не обрабатывает аргументы «ключ-значение» или методы класса (отсутствие аргумента self), но вы видите картину.

Обратите внимание, что следующие утверждения равны:

@somedecorator
def func1(): pass
# ... same as ...
def func2(): pass
func2 = somedecorator(func2)

Вы даже можете сделать так, чтобы декоратор выполнял какую-то функцию, которая выполняет клонирование и, таким образом, позволяет пользователю декоратора выбирать стратегию клонирования. В этом случае декоратор, вероятно, лучше всего реализовать как класс с переопределенным __ call __ .

32
ответ дан 24 November 2019 в 19:05
поделиться

Я не могу найти другой питонический вариант. Но лично я бы предпочел более OO способ.

class TheData(object):
  def clone(self):  """return the cloned"""

def f(data):
  #do stuff

def caller():
  d = TheData()
  f(d.clone())
2
ответ дан 24 November 2019 в 19:05
поделиться

обычно при передаче данных во внешний API вы можете гарантировать целостность ваших данных, передав их как неизменяемый объект, например, заключив ваши данные в кортеж. Это нельзя изменить, если это то, что вы пытались предотвратить своим кодом.

3
ответ дан 24 November 2019 в 19:05
поделиться

Хотя я уверен, что на самом деле не существует питонического способа сделать это, я ожидаю, что модуль pickle предоставит вам копии всего, что у вас есть бизнес, чтобы рассматривать как ценность.

import pickle

def f(data):
    data = pickle.loads(pickle.dumps((data)))
    #do stuff
1
ответ дан 24 November 2019 в 19:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: