İki sınıf arası etkileşimi nasıl sağlarım?

A sınıfımın içinde A1 fonksiyonum bulunuyor. B sınıfında bir olay gerçekleştiğinde A sınıfı çalışır durumdayken A1 fonksiyonunu tetiklemek istiyorum ve A sınıfında ki döngü A1’de ki değişikliği işlesin istiyorum bu mümkün mü? Nasıl gerçekleştirebilirim?

kodlarını paylaşsan sorunu daha doğru anlar ve daha kolay yardımcı olabilirdik.

anladığı oranda basit bir kod yazayım.

Bak bakalım anlatmak istediğin şeye çözüm bu mu?

KOD:

class A:
    def A1(self):
        print("A sınıfının, A1 Fonksiyonu/Metodu")

class B:
    def B1(self):
        print("B sınıfının, B1 Fonksiyonu/Metodu")
    
    def B2(self):
        A.A1(self)

a = A()   # A sınıfından bir nesne oluştur.
b = B()   # B sınıfından bir nesne oluştur.

b.B1()    # B sınıfından oluşan  nesnenin B1 fonksiyonunu/Metodu çağır
b.B2()    # B sınıfından oluşan  nesnenin B2 fonksiyonunu/Metodu çağır, o da A sınıfının A1 fonksiyonunu/Metodunu çağırsın

Çıktı:

B sınıfının, B1 Fonksiyonu/Metodu
A sınıfının, A1 Fonksiyonu/Metodu

B.py

class B:
    def __init__(self):
        self.durum = True
        self.B1()

    def B1(self):
        while True:
            print(self.durum)

    def B2(self):
        self.durum = False

A.py

import B
class A:
    def __init__(self):
        B.B2()

B.py adında python dosyam var ve bu dosya sürekli olarak while dongüsüyle self.durumun sonucunu yazdırmakta.
ben a sınıfının içinden b2 fonksiyonunu çalıştırıp döngüden False sonucu alabilir miyim?

Tekrar merhaba,

Bu konu beni aşıyor.
Mevcut bilgim ile, yapmak istediğine ve kodu bakıyorum, çözüm bulamıyorum.

class B:
    def __init__(self):
        self.durum = True
        self.B1()

    def B1(self):
        while True:
            print(self.durum)

    def B2(self):
        self.durum = False

Bu kod, sonsuz döngüye girmiş görünüyor.
bir soru sorulup, alınan cevaba göre sonsuz döngü mantığı kurulsa, soruya karşılık A sınıfı çalıştırılıp döngü sonlandırılabilir ya da sonsuz döngü çıktısı değiştirilebilir.

Gördüğüm kadarı ile manuel müdahale ile durdurmadığımız ya da bilgisayar müdahale etmediği sürece kodun sonsuz döngüde kalacak.

Mesele sonsuz döngüde olması değil hocam. Mesele; sonsuz döngüde olan classı başka bir classdan müdahale edip b2 fonksiyonu ile True olan çıktıyı False yapabilmek. Thread ile de çalıştrılabilir B1

Anladığım kadarıyla ben şöyle bir şey yapardım:

import threading

class B:
    def __init__(self):
        self.durum = True
        self.control()

    def control(self):
        threading.Thread.Thread(target=self._control).start()
    
    def _control(self):
        while self.durum:
            print(self.durum)
class A:
    def change_attr(self,obj):
        setattr(obj,"durum",False)


instance = B()
A().change_attr(instance) 

Sınıflar çalışmaz. Sınıfları çalıştıramazsın. Sınıflardan türetilen nesneler çalıştırılır.

Alternatif olarak super() diye bir şey duydun mu?

Super sınıflar miras alarak nesne oluşturulduklarında bir erişim ve etkileşim daha kolay olabilir.

What is super() in Python? (educative.io)

Şimdi burada nesneye yönetlik programlama (OOP) sınıf, nesne, kalıtım miras anlatarak sıkmak istemem.

What’s the best way to share a simple helper method between two Python3 classes? : Python (reddit.com)

İmkanın olursa yukarıdaki linkteki konuyu okuyabilirsin.

1 Beğeni

yani başka bir sınıfın veya fonksiyonun içinden sınıfdan ayrı olarak yalnız fonksiyonu çalıştıramam doğru mu anladım?

Çalıştırabilirsin, örneği verilmiş yukarıda.

Sınıflar arası fonksiyonları paylaşmak yerine bir süper sınıf ile daha kolay değil mi?

Use inheritance. Create a base class containing the helper method and have the two other classes inherit from it. This is using inheritance for code reuse.

Create a separate class, Helper, with helperMethod in it, and each of the two classes that need the helper method just call Helper().helperMethod(). This is using composition instead of inheritance.

Define the helper function at module scope and do helperMethod = function in the two class bodies.

Define the helper method in Class1 and in Class2 do helperMethod = Class1.helperMethod. This is an asymmetric variant of the previous option and seems less appealing.

Create a decorator to inject the helper method into each class. This seems like overkill.

Verdiğim linkteki başlangıç mesajındaki teklifler.

Miras kullanın. Yardımcı yöntemi içeren bir temel sınıf oluşturun ve diğer iki sınıfın ondan miras almasını sağlayın. Bu, kodun yeniden kullanımı için kalıtım kullanıyor.

Helper, içinde helperMethod olan ayrı bir sınıf oluşturun ve helper yöntemine ihtiyaç duyan iki sınıfın her biri sadece Helper().helperMethod()'u çağırın. Bu, kalıtım yerine kompozisyon kullanıyor.

Modül kapsamında yardımcı işlevi tanımlayın ve iki sınıf gövdesinde helperMethod = function yapın.

Yardımcı yöntemi Class1'de tanımlayın ve Class2'de helperMethod = Class1.helperMethod yapın. Bu, önceki seçeneğin asimetrik bir çeşididir ve daha az çekici görünmektedir.

Her sınıfa yardımcı yöntemi enjekte etmek için bir dekoratör oluşturun. Bu aşırıya kaçmış gibi görünüyor.

Bunun dışında önerisi olan var mı diye devam etmiş.

Ama en kolayı “bence” bir süper sınıfla erişim kolaylığı.

1 Beğeni

@semtex hocamızın dediği şey daha mantıklı. Ama illa ki zorlamak isterseniz:

import threading

class B:
    def __init__(self):
        self.durum = True
        self.save_instance(self)
        self.control()

    def control(self):
        threading.Thread(target=self._control).start()
    
    def _control(self):
        while self.durum:
            print(self.durum)
    
    @classmethod
    def change_attr(cls):
        setattr(cls.instance,"durum",False)
     
    @classmethod      
    def save_instance(cls,obj):
        cls.instance = obj
        
class A:
    def __init__(self):
        B.change_attr()


instance = B()
A() 
2 Beğeni

Mantıklı demeyelim, yoğurt yeme meselesi, herkesin yoğurt yemesi farklı. Her türlü olur, önemli olan hangisini daha rahat uygulayıp öğrenebileceği o da kişiye göre değişir.

Çözüm çözümdür :wink:

1 Beğeni

Valla hocam bana sizin dediğiniz daha mantıklı geldi. Bir sınıfa dışarıdan zorla müdahale edince içimden çok “çirkin” olduğu hissi geliyor.

Yazmış olduğum sistemde karşılaştığım problemi en törpülenmiş şekilde size aktarmaya çalıştım ama beceriksiz oldum A.py ve B.py örnekleriyle :melting_face: Çözüme maalesef kavuşamadım.

İki farklı py dosyasından bahsetmekteyim.

Pyqt5 ile yapmış olduğum bir gui var. Gui içinde bir fonksiyon while döngüsüyle sürekli durum değişkenin true olup olmadığını kontrol ediyor. Başka bir python dosyasındada ise bir fonksiyon bazı zamanlarda tetiklenmekte. Tetiklendiği vakit Guinin bulunduğu sınıfında ki durum değişkenin True olmasını istiyorum.

Umarım anlatabilmişimdir :melting_face: :melting_face:

Yani bir değişken var ortada ve biri sürekli kontrol edecek diğeri de arada bu değişkeni değiştirebilecek;

O zaman sadece erişim gerektiren bir değişken neden fonksiyonlara erişim konuştuk şimdiye kadar?

Demek ki yine yanlış anlamışız.

İşe yarar mı bilmem önerilmemiş ama global bir değişken tanımlayıp, nesneye çekmek ve kontrol etmek diğer nesne ile de global değişkeni arada değiştirsek olmaz mı?

class - Sharing global variables between classes in Python - Stack Overflow

EDIT:

Yine aklıma gelen, eğer thread kullanacaksanız, global değişkenler için;

python - Using a global variable with a thread - Stack Overflow

Benzeri konulara da dikkat etmeniz gerekir.

EDIT 2:
qt5 gui denildiğinde aklıma geldi. Konsol uygulaması yapanlar, görsel programlamaya geçince biraz zorlanıyor.

Görsel programlamada event driven (olay güdümlü) bir yapı var. Bu şu demek siz bir olay tetiklersiniz o olayın sahibi tepki verir.

Siz bir butona tıklarsınız. Bir olay meydana gelir, ilgili tetiklenen olay kodu tetiklenir.

Bu nedenle konsoldaki gibi for döngüleri, while döngülerini doğrudan buton koduna bağlamak donmaya neden olabilir.

Sınıfların ayrı yerde durmasından ve bir biriyle ilişkilerinden ziyade, olay yönetimi problemi gibi duruyor.

Bunun için
QEvent Class | Qt Core 6.3.2
The Event System | Qt Core 6.3.2

Konulara bakmalısınız.

Bir olay oluşturduğunuzda ilgili sınıf ona tepki vermiş olur.

Yoksa threadler vs içinde boğulur iyice kafanız karışabilir.

Sanki sorun sınıf değil olay yönetimi sorunu gibi geldi.

1 Beğeni

değişkeni dışardan erişmeyi planladığım fonksiyonlar sayende güncellemeyi düşünüyordum. Global aklıma gelmedi maalesef :persevere: :persevere:

Şimdi globalı denedim ve beceriksiz oldum. diğer py dosyasında güncellediğimde ana sınıfda değişiklik olmuyor.

Kusura bakmayın lütfen yüzeysel takılıyorum pythonda derinlemesine bilgim yok.

Bu işi en ilkel yöntemde yapacağım sanırım.

Ana Dosya

while True:
  text = open("kontrol.txt","r")
  durum = text.readlines()[0]
    if durum == True:
             print("tamam")

Yan Dosya

text = open("kontrol.txt","w")
text.write("True")

Aklıma başka bir çözüm yolu gelmedi

Kendimi anlatamadım kusura bakmayın sizi de yordum.
Yardımlarınız için çok teşekkür ederim… sağolun

Bir şeyi gözden kaçırıyoruz.

Bir ara bir örnek üzerinde deneyerek bakalım.

While döngüsüne giren bir değişken o esnada değişkenin değişmesini engelliyor olabilir. Değişkeni sınıfın başında tanımlayıp, fonksiyonla loop döngüsüne çekerek belki güncel kalması garanti edilebilir. Globali while içinde kullanmak yerine bir fonksiyonun return üne yazın.

O fonksiyonu while içinde çekin.

Belki işe yarar.

Elimizde tam kod olmadan bizimki tahmin.

Bir ara fırsatım olursa bir örnek yapar bakarız.

Edit bir ihtimal daha;

Eğer değişkeni referans tipi seçerseniz, erişim kolay olabilir.

Python Value ve Referans Veri Tipleri (sadikturan.com)

Yani referans tipinde olan global bir liste değişkeni kullanırsanız, değişiklikler güncellenir, değer ile alınanlar güncellenmez.

Tam olarak bu yuzden kodun paylasilmasini istiyoruz. (bkz: Soru Sorarken Sıkça Düşülen Hatalar #5) 12 cevapta gelinmis nokta bu. Daha da surecek, cunku birkac tur daha git-gel yapmak lazim. Ben de baska bir yerden soruyorum:

Bahsedilen iki sinifin orneklerini kim yaratiyor?
Programin calisan ilk satiri bile olsa bir noktada ortak atalari var. O noktadan mevcut noktaya nasil geliniyor?

Yukaridan ornek verirsek

2 Beğeni