Cześć,
Jak można przekazać obiekt do funkcji w klasie przez referencję, czy jest to możliwe, nie bardzo mogę znaleźć informacje na ten temat.....
Problem mam taki, że przekazuje instancję obiektu jakiejś własnej klasy do funkcji w celu wykonania operacji na tym obiekcie. Niestety w funkcji pracuję już na innej instancji, tworzy się kopia, sprawdzałem przy pomocy funkcji id(), czy jest jakiś sposób by przekazać go przez referencje, ewentualnie obejście tego progremu?

- Rejestracja:ponad 16 lat
- Ostatnio:około rok

- Rejestracja:ponad 8 lat
- Ostatnio:około 7 godzin
Niestety w funkcji pracuję już na innej instancji, tworzy się kopia
To raczej nie jest prawda
Patrz:
>>> class Foo:
... def __init__(self):
... self.bar = 'asd'
...
>>> x = Foo()
>>> x
<__main__.Foo object at 0x7fbfee9ddd30>
>>> x.bar
'asd'
>>> def modify(o):
... o.bar = 'spam'
...
>>> modify(x)
>>> x.bar
'spam'

- Rejestracja:około 8 lat
- Ostatnio:około 7 godzin
- Postów:4902
Modyfikujesz pole obiektu, czyli to do czego wskaźnik się odnosi, ale na stosie jest kopia samego obiektu, (referencji do niego) i jego w funkcji, zmienić nie można; dlatego:
class Foo:
def __init__(self):
self.f = "bar"
def modify(obj):
obj = "baz"
f1 = Foo()
print(f1) # -> <__main__.Foo object at 0x7faeac165910>
modify(f1)
print(f1.f, f1) # -> bar <__main__.Foo object at 0x7faeac165910>

- Rejestracja:ponad 16 lat
- Ostatnio:około rok
Jestem początkujący w pythonie i pewnie czegoś nie ogarniam. Staram się zrobić pewien mechanizm, który zrobiłem kiedyś w c c#. W skrócie chodzi o to, by załadować dynamicznie klasy pluginów i uruchomić ich instancje tak, by każda działała w osobnym procesie.
- każda wtyczka może kręcić się nieskończenie długo i bardzo długo nie zwracać wyniku
- zinstancjownowane wtyczki znajdują się w tablicy __plugin_instances
- każda wtyczka dziedziczy po pewnej klasie abstrakcyjnej, która ma zapewnić jednolity interfejs (metody init() i run())
W momencie uruchomienia funkcji run_all_by_configuration tablica instancji jest przekazywana do ProcessPoolExecutor, który przy pomocy funkcji launch_plugin uruchamia procesy - w tej funkcji plugin ma już inne id, następnie w uruchamianej cyklicznie funkcji check_plugins() chce kontrolować stan wtyczek ale widzę, że obiekty w __plugin_instances się nie zmieniają. Zakładam, że coś robię nie tak
class InterfaceManager:
__plugin_loader: PluginLoader
__pool_executor: concurrent.futures.ProcessPoolExecutor
__scheduler: sched.scheduler
__configuration_tree: []
__plugin_instances: []
__workers_number: int
__scheduler_delay: int
def __init__(self, configuration_tree):
self.__plugin_loader = PluginLoader(Parameters.inrastructure_plugins_dir)
self.__configuration_tree = configuration_tree
self.__workers_number = len(configuration_tree)
self.__pool_executor = concurrent.futures.ProcessPoolExecutor(max_workers=self.__workers_number)
self.__plugin_loader.load_all_plugins()
self.__scheduler = sched.scheduler(time.time, time.sleep)
self.__scheduler_delay = Parameters.scheduler_delay_for_im
def verify_configuration(self) -> bool:
p_i = [x for x in self.__configuration_tree if
x.enabled == 1 and
x.plugin_type.processing_type == Enums.ProcessingType.PROCESSING.value and
x.plugin_type.manager_type == Enums.ManagerType.INTERFACE.value
]
self.__configuration_tree = p_i
if len(self.__configuration_tree) > 0:
return True
else:
return False
def init_by_configuration(self):
self.__plugin_instances = []
for conf in self.__configuration_tree:
pl = self.__plugin_loader.plugins[conf.plugin_type.library_name]
plugin = pl()
plugin.init(conf.name, conf.plugin_instance_configurations)
self.__plugin_instances.append(plugin)
# print(id(plugin))
def run_all_by_configuration(self):
if len(self.__plugin_instances) > 0:
self.__pool_executor.map(self.launch_plugin, self.__plugin_instances)
self.__scheduler.enter(self.__scheduler_delay, 1, self.__check_plugins)
self.__scheduler.run()
def run_single(self):
pass
def __check_plugins(self):
for plugin_instance in self.__plugin_instances:
print(id(plugin_instance))
print('Status dla %s - %s', plugin_instance.instance_name, plugin_instance.is_working)
# print(dir(plugin_instance))
# print(id(plugin_instance))
self.__scheduler.enter(self.__scheduler_delay, 1, self.__check_plugins)
@classmethod
def launch_plugin(cls, plugin): # todo: try catch
print(id(plugin))
plugin.run()
- screenshot-20210217141658.png (22 KB) - ściągnięć: 27

- Rejestracja:prawie 7 lat
- Ostatnio:dzień
- Lokalizacja:Kraków
- Postów:1999
Jeśli modyfikujesz obiekty w innych procesach, to problem nie leży w przekazywaniu ich do funkcji ;)
Co do zasady procesy nie współdzielą pamięci, każdy będzie miał własną kopię tych obiektów w zaalokowanej dla siebie pamięci i tak dalej.
Co prawda powinno dać się to "ohakować", stosując pamięć współdzieloną - ale wtedy musisz mieć pewność, że procesy z puli będą z niej korzystały i te obiekty musiałyby żyć w pamięci współdzielonej właśnie. Pamiętam, że kiedyś coś takiego robiłem, bo FileLock
i sprawiały za dużo problemów, a Pythonowe read/write-locki działały tylko na wątkach. Więc właśnie w oparciu o shared mem wyrzeźbiłem prosty RWLock działający z procesami, także dać się da ;)
https://docs.python.org/3/library/multiprocessing.shared_memory.html
https://stackoverflow.com/a/14135569



- Rejestracja:około 9 lat
- Ostatnio:ponad 2 lata
Tak dla uporządkowania -- w Pythonie wszystko jest przekazywane przez wskaźnik, nie ma przekazywania przez referencję (przynajmniej tak, jak to się rozumie np. w C++).
A więc nie możemy zmienić przekazanego obiektu na inny, ale możemy zmienić jego zawartość...

ale na stosie jest kopia samego obiektu
no nie kopia tylko wskaznik na obiekt, ktorego funkcja nie moze zmienic