Memanggil fungsi kelas di dalam __init__

132

Saya sedang menulis beberapa kode yang mengambil nama file, membuka file, dan mem-parsing beberapa data. Saya ingin melakukan ini di kelas. Kode berikut berfungsi:

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()

Tapi itu melibatkan saya menempatkan semua mesin parsing dalam lingkup __init__fungsi untuk kelas saya. Itu terlihat bagus sekarang untuk kode yang disederhanakan ini, tetapi fungsinya parse_filememiliki beberapa level indention juga. Saya lebih suka mendefinisikan fungsi parse_file()sebagai fungsi kelas seperti di bawah ini:

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

Tentu saja kode ini tidak berfungsi karena fungsinya parse_file()tidak dalam cakupan __init__fungsi. Apakah ada cara untuk memanggil fungsi kelas dari dalam __init__kelas itu? Atau apakah saya memikirkan hal ini dengan cara yang salah?

PythonJin
sumber
Apakah ada alasan contoh kode membutuhkan lima versi "stat"? Akan lebih mudah dibaca jika hanya ada satu.
465b

Jawaban:

183

Panggil fungsi dengan cara ini:

self.parse_file()

Anda juga perlu mendefinisikan fungsi parse_file () Anda seperti ini:

def parse_file(self):

The parse_fileMetode harus terikat ke objek pada menyebutnya (karena itu bukan metode statis). Ini dilakukan dengan memanggil fungsi pada instance objek, dalam kasus Anda instance adalah self.

Lewis Diamond
sumber
Iya! Ini persis apa yang saya cari. Terima kasih!
PythonJin
33

Jika saya tidak salah, kedua fungsi adalah bagian dari kelas Anda, Anda harus menggunakannya seperti ini:

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

ganti baris Anda:

parse_file() 

dengan:

self.parse_file()
Paritosh Singh
sumber
Bisakah Anda menjelaskan mengapa itu harus digunakan self.parse_file()dan tidak parse_file()?
ivanleoncz
@paritoshsingh seharusnya def parse_file(self):tidak bersarang di bawah __init__fungsi sehingga Anda tidak memiliki objek yang diinisialisasi sebagian?
donrondadon
@ivanleoncz Karena parse_file adalah metode instance, kita perlu menggunakan objek referensi untuk memanggil yang sama.
Paritosh Singh
@rong Jika kode ini terhormat dan Anda tidak ingin mengizinkan pengaturan file parse dari luar, ya itu harus disarangkan.
Paritosh Singh
12

Bagaimana tentang:

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

By the way, jika Anda memiliki variabel bernama stat1, stat2, dll, situasi ini mengemis untuk tupel: stats = (...).

Jadi, parse_filekembalikan tupel, dan simpan tupelnya self.stats.

Kemudian, misalnya, Anda dapat mengakses apa yang dulu disebut stat3dengan self.stats[2].

unutbu
sumber
Saya setuju, saya hanya menempatkan self.stat1 melalui self.stat5 di sana untuk menunjukkan bahwa ada beberapa variabel kelas yang saya tetapkan. Dalam kode aktual saya punya solusi yang lebih elegan.
PythonJin
Bagaimana ini harus diubah jika saya ingin parse_filefungsi menjadi metode MyClassobjek. Di mana akan selfdiperlukan?
n1k31t4
0

Di parse_file, ambil selfargumen (seperti di __init__). Jika ada konteks lain yang Anda butuhkan maka berikan saja argumen tambahan seperti biasa.

Teo Klestrup Röijezon
sumber
0

Anda harus mendeklarasikan parse_file seperti ini; def parse_file(self). Parameter "mandiri" adalah parameter tersembunyi di sebagian besar bahasa, tetapi tidak dalam python. Anda harus menambahkannya ke definisi semua metode yang dimiliki kelas. Kemudian Anda dapat memanggil fungsi dari metode apa pun di dalam kelas menggunakanself.parse_file

program akhir Anda akan terlihat seperti ini:

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
Ionut Hulub
sumber
-13

Saya berpikir bahwa masalah Anda sebenarnya dengan indentasi fungsi init yang tidak benar. Seharusnya seperti ini

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

     def parse_file():
          pass
Zed
sumber
Kode Anda juga tidak. Kecuali Anda meletakkan @staticmethoddekorator di atas parse_file
rantanplan
setidaknya tambahkan yang hilang selfdalam parse_filemetode Anda .
rantanplan
Ups, maaf seharusnya ada lapisan tambahan indentasi di bawah baris "class MyClass ():". Saya sudah memperbaikinya di atas, tetapi pertanyaannya tetap sama.
PythonJin