Python derleyici yapma

çok teşekkür ederim yardımcı olduğun için.

1 Beğeni

Bu arada, kodlara renklendirme eklemek isterseniz Pygments modülünü kullanabilirsiniz. Kolay gelsin! :slight_smile:

sağolasın imkan bulursam bakacağım inş.

import subprocess
subprocess.check_output([sys.executable, dosya.py]).decode('utf-8').rstrip()

Bu kod python ile dosya.py 'yi çalıştırıp sonucu bize veriyor.

fakat şimdi istediğim dosya.py yerine herhangi bir texti(yazıyı) çalıştırıp sonucu bana versin.
python tanımlı komut satırı veya terminale böyle yazdığımda

python -c "a = 3; print(a)"

sonucu gösteriyor ve ben bu sonucu komut satırından alabiliyorum ama birçok kodtada hata veriyor örneğin

python -c print("deneme")

yazdığımda “deneme”(çift tırnaklı) yerine tek tırnaklı ‘deneme’ yazarsam oluyor.
Bu ve bunun gibi eksiklikleri yüzünden işime yaramadı.

herhangi bir yazıyı(kodu) python 'da çalıştırıp sonucu bana verecek bir çözüme ihtiyacım var.

Yazılan kodu bir dosya içine yazdırın o dosyayı çalıştırın.

yapacağım projede böyle yapınca bazı sorunlar oluyor.Proje python komut kabuğu(shell) gibi komutları tkinter ile yaptığım entrye yazıyorum enterlediğimde sonucu alta yazıyor. Her yazdığım kodu dosyaya kaydedip çalıştırırsam eski kodlarıda çalıştırıyor.

IDLEnin kaynak koduna bakın belki orda bulabilirsiniz.

o kadar iyi değilim :smiley: kaynak kodu nerde bulabilirim büyük ihtimalle baksamda anlamam anlasamda o kadar kodun arasında nasıl bulacam :sweat_smile:

Kodlar düzenli ancak basit değil. Yani 20-30 tane dosya var. Ancak okumak biraz sıkıntı.

Burada çift tırnak sebebiyle sorun çıkması; çift tırnağın, terminalde kullanılan çift tırnak ile karışması sebebiyledir. Normalde bu şekilde her Python kodunu çalıştırabilirsiniz (Birden fazla satır süren kodları noktalı virgül ile ayırmanız gerekir.). Sorununuzu çözmek için kodu tırnak içine almayı deneyin:

python -c "print('deneme')"

Bunu ben biliyorum yaparım ama yapacağım programa entegre edersem kullanışlı olmaz her kod yazana bunu dayatmış olurum
Bu şekilde kod yazılırsa def, if vs. komutu verilemiyor if ve else beraber kullanılırsa bir yöntem var aslında def yerinede lambda kullanılabilir ama programda bu yöntem kullanılırsa kullanıcıyı python kodlarken kısıtlamış oluyoruz

StringIO sınıfını bir araştırın derim o zaman. Karakter dizilerini dosya gibi kullanabilmenize imkan sağlıyor. İstediğiniz şey olabilir. Gerçi exec ve eval gömülü fonksiyonları ile de karakter dizisi halindeki Python kodunu çalıştırabilirsiniz.

Hocam sanırım exec işimi görür neden aklıma gelmedi bilmiyorum lakin exec 'in çıktısını nasıl alabilirim?

exec() fonksiyonunu çalıştırdığınızda sonuçlar standart çıktı konumuna (sys.stdout) veya standart hata konumuna (sys.stderr) yazdırılır. Bu konumları bir widgete (örneğin text widgetine) yönlendirebilirsiniz.

stdout ile exec çıktısını nasıl alabilirim?

Aşağıdaki örnekte, stdout ve stderr resmin sağ tarafındaki text widgetine yönlendirilmiştir. İsterseniz kodları bir inceleyin, belki işinize yarar.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

root = tk.Tk()


def widgetleri_olustur():
    for i, j in enumerate(("Çalıştır", "Temizle")):
        text = tk.Text(master=root)
        text.grid(row=0, column=i)
        button = tk.Button(master=root, text=j)
        button.grid(row=1, column=i)
        yield text
        yield button


t1, b1, t2, b2 = widgetleri_olustur()


class StdIOYonlendiricisi:
    """
    Bu sınıfta sys.stdout'un write, flush
    özelliklerine benzer özellikler tanımladık.
    Bu özelliklerin yapısı, widgetin
    yapısına uygun olacak şekilde düzenlendi.
    Böylece standart çıktıları bir widgete yönlendirebiliriz.
    """
    def __init__(self, text):
        self.text = text

    def write(self, string):
        self.text.insert("insert", string)

    def flush(self):
        self.text.update()


sys.stdout = StdIOYonlendiricisi(text=t2)
sys.stderr = StdIOYonlendiricisi(text=t2)


def command1():
    exec(t1.get("1.0", "end"))


def command2():
    t2.delete("1.0", "end")


b1.configure(command=command1)
b2.configure(command=command2)
root.mainloop()

sys.stdout = class olmak zorundamı?

Başka bir yöntem varsa da bilmiyorum.

write fonksiyonu olan herhangi bir şey olabilir. flush da gerekli gibi duruyor ancak emin değilim. @dildeolupbiten sen biliyor musun?

@ismailarilik’in bahsettiği gibi write fonksiyonu olan bir veri tipi gerekiyor.
Normalde tk.Text() widgetine yazı yazma fonksiyonu tk.Text().insert("insert", string). Dolayısıyla sys.stdout'u, tk.Text() widgetine doğrudan yönlendiremeyiz. Yönlendirebilmek için write() metodu olan bir veri tipine ihtiyaç var. Bu veri tipini bir sınıf ile oluşturabiliriz. Bu sınıfın örnek metotlarının bir tanesi (write() olan) tk.Text() widgetinin tk.Text().insert("insert", string) fonksiyonunu çalıştırır. Özetle bu sınıfın metotlarının isimleri tıpkı sys.stdout'un metotlarının ismine benzer olursa, sys.stdout'u sınıfa yönlendirebiliriz.

flush()‘ı eklemezsek şöyle bir durumla karşılaşabiliriz:
Program çalışırken, sys.stdout.flush() fonksiyonunu veya print(string, flush=True) fonksiyonunu kullanırsak bir AttributeError hatası alırız (AttributeError: ‘StdIOYonlendiricisi’ object has no attribute 'flush’).

Bir de, şu hatırlatmayı da yapmak isterim. Diyelim widgetin içine aşağıdaki kodları yazdık:

import time
count = 1
while count < 10:
    print(count)
    count += 1
    time.sleep(1)

Bu kodların çıktısı, widgetin şu haliyle ancak 10 saniye sonra standart çıktılara yazdırılır ve bu arada program geçici olarak donar.

Bu durumu önlemenin bildiğim kadarıyla üç yolu var:

  1. Ya yukarıdaki kodları şöyle yazacağız:
import time
count = 1
while count < 10:
    print(count, flush=True)
    count += 1
    time.sleep(1)
  1. Ya, aşağıdaki gibi olan command1() fonksiyonunu;
def command1():
    exec(t1.get("1.0", "end"))

Şu şekilde değiştireceğiz:

def command1():
    def inner_function():
        exec(t1.get("1.0", "end"))

    thread = threading.Thread(target=inner_function)
    thread.daemon = True
    thread.start()

exec() fonksiyonunu bir iş parçacığının hedefi haline getirirsek, exec() fonksiyonunun yürüttüğü işlem, Tkinter uygulamasına engel olmaz.

  1. Ya da, StdIOYonlendiricisi() sınıfının write() metodunu şu şekilde değiştireceğiz:
def write(self, string):
    self.text.insert("insert", string)
    self.flush()

Yani her write() metodu kullanımında aynı zamanda flush() metodunu da kullanacağız.

1 Beğeni