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:ponad rok

- Rejestracja:ponad 8 lat
- Ostatnio:8 minut
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:minuta
- Postów:4930
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:ponad 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:2 dni
- Lokalizacja:Kraków
- Postów:2000
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ść...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.
ale na stosie jest kopia samego obiektu
no nie kopia tylko wskaznik na obiekt, ktorego funkcja nie moze zmienic