__İnit__ içinde bir sınıf işlevini çağırma


133

Dosya adı alan, dosyayı açan ve bazı verileri ayrıştıran bir kod yazıyorum. Bunu bir sınıfta yapmak istiyorum. Aşağıdaki kod çalışır:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None

        def parse_file():
            #do some parsing
            self.stat1 = result_from_parse1
            self.stat2 = result_from_parse2
            self.stat3 = result_from_parse3
            self.stat4 = result_from_parse4
            self.stat5 = result_from_parse5

        parse_file()

Ama tüm ayrıştırma makinelerini __init__sınıfımın işlevinin kapsamına koymamı gerektiriyor . Bu basitleştirilmiş kod için şimdi iyi görünüyor, ancak işlevin parse_filede epeyce girinti seviyesi var. parse_file()İşlevi aşağıdaki gibi bir sınıf işlevi olarak tanımlamayı tercih ederim :

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        parse_file()

    def parse_file():
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

Elbette bu kod çalışmıyor çünkü işlev işlevin parse_file()kapsamında değil __init__. Bu sınıfın içinden bir sınıf işlevini çağırmanın bir yolu var mı __init__? Yoksa bunu yanlış bir şekilde mi düşünüyorum?


Kod örneğinin beş "stat" sürümüne ihtiyaç duymasının herhangi bir nedeni var mı? Sadece bir tane olsaydı okumayı kolaylaştırırdı.
— 465b

Yanıtlar:


185

İşlevi şu şekilde çağırın:

self.parse_file()

Ayrıca parse_file () işlevinizi şu şekilde tanımlamanız gerekir:

def parse_file(self):

parse_fileYöntemi (statik bir yöntem değildir çünkü) o çağrı üzerine bir nesneye bağlı olması gerekir. Bu, nesnenin bir örneğinde işlevi çağırarak yapılır, sizin durumunuzda örnek olur self.


Evet! Bu tam olarak aradığım şeydi. Teşekkür ederim!
— PythonJin

33

Yanılmıyorsam, her iki fonksiyon da sınıfınızın bir parçası, bunu şu şekilde kullanmalısınız:

class MyClass():
    def __init__(self, filename):
        self.filename = filename 

        self.stat1 = None
        self.stat2 = None
        self.stat3 = None
        self.stat4 = None
        self.stat5 = None
        self.parse_file()

    def parse_file(self):
        #do some parsing
        self.stat1 = result_from_parse1
        self.stat2 = result_from_parse2
        self.stat3 = result_from_parse3
        self.stat4 = result_from_parse4
        self.stat5 = result_from_parse5

satırınızı değiştirin:

parse_file() 

ile:

self.parse_file()

O kullanılmalıdır neden açıklayabilir misiniz self.parse_file()değil parse_file()?
— ivanleoncz

@paritoshsingh, kısmen başlatılmış bir nesneye sahip olmamak def parse_file(self):için __init__işlevin altına yerleştirilmemelidir ?
— donrondadon

@ivanleoncz parse_file örnek yöntemi olduğundan, aynı şeyi çağırmak için referans nesnesini kullanmamız gerekir.
— Paritosh Singh

@rong Bu kod saygıdeğerse ve ayrıştırma dosyasını dışarıdan ayarlamaya izin vermek istemiyorsanız, evet iç içe yerleştirilmelidir.
— Paritosh Singh

12

Peki ya:

class MyClass(object):
    def __init__(self, filename):
        self.filename = filename 
        self.stats = parse_file(filename)

def parse_file(filename):
    #do some parsing
    return results_from_parse

Adlandırılmış değişkenleri varsa arada, stat1, stat2vb durum demet için yalvarıyor: stats = (...).

Öyleyse parse_filebir demet iade edin ve demeti içeride saklayın self.stats.

Sonra, örneğin, çağrılacak eskiden ne erişebilir stat3ile self.stats[2].


Katılıyorum, atadığım bazı sınıf değişkenlerinin olduğunu göstermek için self.stat1'i self.stat5'e koydum. Gerçek kodda daha zarif bir çözümüm var.
— PythonJin

parse_fileİşlevin MyClassnesnenin bir yöntemi olmasını istersem, bu nasıl değiştirilmelidir ? Nereye selfihtiyaç duyulur?
— n1k31t4

0

İçinde parse_file, selfargümanı alın (tıpkı içindeki gibi __init__). İhtiyacınız olan başka bir bağlam varsa, bunu her zamanki gibi ek argümanlar olarak iletin.


0

Parse_file'ı bu şekilde bildirmelisiniz; def parse_file(self). "Self" parametresi çoğu dilde gizli bir parametredir, ancak python'da değildir. Bunu bir sınıfa ait olan tüm yöntemlerin tanımına eklemelisiniz. Daha sonra işlevi kullanarak sınıfın içindeki herhangi bir yöntemden işlevi çağırabilirsiniz.self.parse_file

son programınız şöyle görünecek:

class MyClass():
  def __init__(self, filename):
      self.filename = filename 

      self.stat1 = None
      self.stat2 = None
      self.stat3 = None
      self.stat4 = None
      self.stat5 = None
      self.parse_file()

  def parse_file(self):
      #do some parsing
      self.stat1 = result_from_parse1
      self.stat2 = result_from_parse2
      self.stat3 = result_from_parse3
      self.stat4 = result_from_parse4
      self.stat5 = result_from_parse5

-13

Bence probleminiz aslında init fonksiyonunun doğru şekilde girintilememesi ile ilgili.

class MyClass():
     def __init__(self, filename):
          pass

     def parse_file():
          pass

Senin kodun da değil. Eğer koymak sürece @staticmethodüstünde dekoratör parse_file
— rantanplan

en azından eksik eklemek selfiçin de parse_fileyöntemle.
— rantanplan

Maalesef "class MyClass ():" satırının altında fazladan bir girinti katmanı olmalıydı. Yukarıda düzelttim ama soru aynı kalıyor.
— PythonJin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.