Global alanda client isminde bir değişken oluşturun, değerini None yapın. Sonra f_ara fonksiyonunun içine client değişkenini, global client yazarak aktarın. Fonksiyonun sonlarında tanımladığınız client, adres = listener.accept() sayesinde, client değişkeninin değerinin değişmesi lazım, sonra da client değişkenini f_gonder() fonksiyonunun içinde kullanabilirsiniz.
global alanda none olarak belirtiğim için 2 .fonksiyonun içinde değerini none olarak alıyor bu hatayı veriyor;
“”"
AttributeError: ‘NoneType’ object has no attribute ‘send’
“”"
yani yapmam gereken değişkeni birinci fonksiyonun içinde globalleştirmek
İsmail Bey’in dediği gibi kodlarınızı burada kod görünümüne alarak paylaşabilir misiniz?
Normalde global alanda bir client değişkeni tanımlayıp, f_ara() fonksiyonunun içinde bu global değişkeni değiştirirseniz, başka bir fonksiyonun içinde kullandığınız client’in değeri değiştirilen değer olur. Bu uygulayabileceğiniz yöntemlerden biridir yeter ki global alandaki client değişkenini değiştirdiğiniz fonksiyonu, client ile işlem yapacağınız diğer fonksiyonlardan önce çalıştırın ki client’in değeri değişsin.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
client = None
def socket_olustur():
global client
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "localhost"
port = 1236
s.bind((host, port))
s.listen(1)
client, address = s.accept()
def gonder():
client.send("merhaba".encode("utf-8"))
# Önce socket_olustur() fonksiyonunu çağırmalısınız ki
# client değişkeninin değeri değişsin. Ki zaten socket işlemleri
# yapabilmek için de önce bu fonksiyonu çağırmalısınız.
socket_olustur()
# Sonra clientin yaptığı işle ilgili başka bir fonksiyonu
# kullanabilirsiniz.
gonder()
Diğer bir yöntem ise İsmail Bey’in de dediği gibi sınıfları kullanmanızdır.
Üçüncü bir yöntem daha var, o da şu: global alanda boş bir liste tanımlayın. client, adres = listener.accept()'i yazdığınız satırdan sonra bu tanımladığınız listeye client’i ekleyin. Başka bir fonksiyonda client’e ihtiyacınız olduğunda bu listenin elemanını kullanabilirsiniz.
Not: Bu bahsettiklerim, sadece arkadaşın takıldığı yerle alakalı bir çözüm üretir. Normalde düzgün bir haberleşmeyle alakalı bir program oluşturabilmek için programa daha çok eklemeler, düzenlemeler yapmak lazım.
Fonksiyonun içinde listenin append metodunu çağırarak, listeye eleman ekledik. Ama mesela liste kullandığımız yerde demet tipinde bir veri kullanamazdık. Yani şöyle anlatmaya çalışayım:
demet = tuple()
def f():
demet += "hello",
print(demet[0])
f()
# Bu işlemi gerçekleştiremeyiz.
Yukarıda yapmak istediğimiz işlemi şu şekilde yazmamız gerekiyor:
Aynı durum str(), int() gibi immutable veri tipleri için de geçerli. Çünkü bunların doğrudan veriye eleman ekleme yöntemleri yok. Mesela bir stringe veya demete eleman eklerken += ifadesini kullanıyoruz. Aynı durum sayıyı değiştirirken de geçerli.
Ama list(), dict(), set() gibi mutable veri tiplerinin kendilerine ait birer eleman ekleme yöntemleri var. Ve bu yöntemler bir fonksiyonun içinde kullanılabilir.
Bu arada, eğer bu immutable veri tiplerine ait yöntemlerin fonksiyon içerisinde kullanılması söz konusuysa, bunun için değişkenin başına global yazarak fonksiyonun içine aktarılması gerekmiyor.
Örneğin:
demet = tuple(["hello", "world"])
def f():
for i in demet:
print(demet.index(i))
f()
Başka bir örnek:
string = "hello"
def f():
for i in string:
print(i)
f()
Kodları buraya ekran görüntüsü olarak değil de kod görünümünde aktarabilir misiniz? Bir de global değişkeni nasıl kullandınız onu da yine kod görünümü içinde paylaşabilir misiniz?
[code]
Kodların tamamının bu aralığa yazılması lazım.
[/code]
İyi ama bu kodlarda f_ara() fonksiyonun içinde global client yok ki. Size daha önceki mesajlarımdan birinde demiştim ki, global client’i f_ara fonksiyonunun içine aktarın, tıpkı aşağıdaki gibi:
Aslında sınıflarla yapılmış socket uygulamalarına dair yeterince örnek Python Socket Ve Threading Kaynak Bilen Var mı? başlığında ve Socket Modülüyle Yapılmış Chat Uygulaması Örnekleri başlığında mevcut. Oradaki çalışmaları inceleyebilirsiniz. İlk linkteki çalışmalar aşama aşama gelişmiş bir iki programın gelişim süreçlerini daha çok konu ediniyor. İkinci linkteki çalışmalar ise sonuçlanmış çalışmaları paylaştığım bir konu oldu.
baktım da class(sınıf) ile tanımlanmış örnek göremedim çok kod olduğundan da olabilir zahmet olmazsa sadece bir örnek paylaşsanız global yerine nasıl yapılır anlamam için maksad kafam karışmasın verdiğim fonksiyonu kullanarakta yapsanız olur
Yazdığınız kodlar şu şekilde sınıfa dönüştürülebilir. Bu arada bu tip uygulamalarda threading’i kullanmanızı öneririm.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import threading
import tkinter as m_tk
import socket as m_soc
fr_form = m_tk.Tk()
class Server(m_soc.socket):
clients = []
def __init__(self):
m_soc.socket.__init__(self, m_soc.AF_INET, m_soc.SOCK_STREAM)
host = "localhost"
port = 1234
self.bind((host, port))
self.listen(1)
def kabul_et(self):
def f():
client, adres = self.accept()
self.clients.append(client)
t = threading.Thread(target=f)
t.start()
def mesaj_gonder(self):
def f():
mesaj = e_mesaj.get()
self.clients[0].send(mesaj.encode("ascii"))
l_label["text"] = "GÖNDERİLDİ"
t = threading.Thread(target=f)
t.start()
def kapat(self):
self.clients[0].close()
server = Server()
e_mesaj = m_tk.Entry(fr_form)
e_mesaj.pack()
l_label = m_tk.Label(fr_form, text = "listener")
l_label.pack()
b_baslat = m_tk.Button(fr_form, text = "BAŞLAT", command=server.kabul_et)
b_baslat.pack()
b_gonder = m_tk.Button(fr_form, text = "GÖNDER", command=server.mesaj_gonder)
b_gonder.pack()
b_kapat = m_tk.Button(fr_form, text = "KAPAT", command=server.kapat)
b_kapat.pack()
fr_form.mainloop()
Yalnız bu uygulama baya eksik bir uygulama. Lütfen okumanızı önerdiğim başlıkların mesajlarını bir okuyun. İnanıyorum ki ciddi bir şekilde okursanız, size faydası olacaktır.
@dildeolupbiten, Allah razı olsun. global konusunu şimdiye kadar tam olarak anlayamamıştım. Anladığım kadarıyla global'in amacı global alandaki değişkenlerin istemsiz şekilde değiştirilmesini engellemek. global değişken_adı yazarak aslında “Ben bu değişkeni burada bilerek değiştiriyorum, herhangi bir sorun yok.” demek istiyoruz. Mutable tipler ve yöntem çağrımları değişkenin değerini değiştirmediği için bunlarda böyle bir ifade kullanmak gerekmiyor.