Python - Совместное использование переменных между различными экземплярами разных классов

1

Я искал следующий ответ, но наверняка я искал неправильные ключевые слова. Раньше я работал с C++, пропуская указатели как ссылки между объектами. Дело в том, что теперь я пытаюсь создать программу на Python, где один экземпляр класса 'General' инициализирует разные экземпляры класса 'Specific' с той же общей переменной.

class General():
    def __init__(self):
        self._shared_variable = 0
        self._specific1 = Specific(self._shared_variable)
        self._specific2 = Specific(self._shared_variable)

class Specific():
    def __init__(self, shared):
        self._shared = shared
    def modify_shared_variable(self):
        self._shared_variable +=1

Итак, что я пытаюсь сделать, так это разделять эту 'shared_variable' пределах общей области, поэтому, когда "конкретный" экземпляр изменяет свою внутреннюю переменную, это изменение видит или отражается другим экземпляром. Но это не относится к питону. Таким образом, каждый конкретный экземпляр имеет свою собственную переменную. Как я могу это достичь?

Теги:
pass-by-reference

1 ответ

1
Лучший ответ

Вы не можете иметь ссылки на переменные в Python. Переменная - это просто имя в каком-либо пространстве имен (обычно __dict__ модуля, класса или объекта экземпляра или специальное локальное пространство имен внутри фрейма функции) для значения.

Вы можете иметь ссылки на значения, но, конечно, числа являются неизменяемыми значениями, поэтому вы не можете изменить число 1 на число 2.

Итак, что вы можете сделать, это создать какое-то изменяемое значение, которое содержит число, и поделиться ссылками на это.


Одна очевидная возможность заключается в том, чтобы просто дать каждому Specific экземпляру ссылку на созданный экземпляр General:

class General():
    def __init__(self):
        self._shared_variable = 0
        self._specific1 = Specific(self)
        self._specific2 = Specific(self)

class Specific():
    def __init__(self, shared_general):
        self._shared_general = shared_general
    def modify_shared_variable(self):
        self._shared_general._shared_variable +=1

Другая возможность состоит в том, чтобы сохранить одноэлементный список:

class General():
    def __init__(self):
        self._shared_variable = [0]
        self._specific1 = Specific(self._shared_variable)
        self._specific2 = Specific(self._shared_variable)

class Specific():
    def __init__(self, shared):
        self._shared = shared
    def modify_shared_variable(self):
        self._shared[0] += 1

(На самом деле это то же самое, что вы делаете в C++, но без синтаксического сахара массивов и указателей - почти одно и то же...)


Или вы можете создать простой класс MutableInteger который будет содержать int, прокси-методы без мутаций, добавляет метод set для его замены и обрабатывает += и другие методы mutating, вызывая set и возвращающий self, вместо того, чтобы возвращать новое значение,

  • 0
    Здравствуй! @abarnert спасибо за быстрый ответ. Я пошел на третий подход и работает мягко! Как вы думаете, это лучшая практика? Спасибо!
  • 0
    @Cristo Это действительно зависит от того, что вы делаете. Лично мне редко приходилось использовать что-то настолько специфичное, как «int holder», которое не было даже более конкретным, например «пользовательский объект» (в котором нет полей, кроме идентификатора пользователя int), но это не Это не значит, что вы не пользуетесь этим. Пока вы думаете о терминах «как мне моделировать эти данные в Python», а не «как я могу перевести эту модель C ++ в модель Python», ваша интуиция, вероятно, будет в порядке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню