Przekazywanie przez referencję

Przekazywanie przez referencję
pieczara
  • Rejestracja:ponad 16 lat
  • Ostatnio:około rok
0

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?

KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:14 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0

Możesz pokazać kod? bo to co mówisz kłóci się z moją (niewielką) wiedzą o Pythonie


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
stivens
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
4

Niestety w funkcji pracuję już na innej instancji, tworzy się kopia

To raczej nie jest prawda

Patrz:

Kopiuj
>>> 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'

λλλ
edytowany 1x, ostatnio: stivens
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około 7 godzin
  • Postów:4902
2

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:

Kopiuj
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>

edytowany 1x, ostatnio: lion137
stivens
ale na stosie jest kopia samego obiektu no nie kopia tylko wskaznik na obiekt, ktorego funkcja nie moze zmienic
lion137
Tak, oczywiście, w zasadzie powinienem to dopisać.
stivens
Chyba w dalszym ciagu mowienie o kopii obiektu jest mylace. Proponuje zedytowac tak zeby tylko o tej referencji byla mowa :P
lion137
Dokładniej nie kopia, ale lokalna nazwa, ale juz bym nie dzielił włosa na czworo...
pieczara
  • Rejestracja:ponad 16 lat
  • Ostatnio:około rok
0

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

screenshot-20210217141658.png

Kopiuj
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()
superdurszlak
  • Rejestracja:prawie 7 lat
  • Ostatnio:dzień
  • Lokalizacja:Kraków
  • Postów:1999
2

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 FileLocki 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


edytowany 1x, ostatnio: superdurszlak
stivens
Z ciekawosci, jak w Pythonie zrobic taka pamiec wspoldzielona? W C bym potrafil ale w Pythonie nie :P
superdurszlak
W sumie bardzo słabo pamiętam. Wydaje mi się, że ja to wtedy obszedłem w dość brzydki sposób, wykorzystując ładowanie modułów do tej pamięci :]
koszalek-opalek
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 2 lata
1

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ść...

PI
No to tak się zachowują referencje c++ To takie stałe wskaźniki ;-)
koszalek-opalek
@pitgal: Nie, w Pythonie mamy inne zachowanie -- a referencje bliskie są stałym wskaźnikom, ale nie tożsame jednak...
PI
No racja różnią się uproszczoną składnią bez potrzeby używania ->
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)