Gọi một hàm lớp bên trong __init__


132

Tôi đang viết một số mã có tên tệp, mở tệp và phân tích một số dữ liệu. Tôi muốn làm điều này trong một lớp học. Các mã sau hoạt động:

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

Nhưng nó liên quan đến việc tôi đặt tất cả các máy phân tích cú pháp trong phạm vi __init__hàm cho lớp của tôi. Điều đó có vẻ tốt cho mã đơn giản hóa này, nhưng chức năng parse_filenày cũng có khá nhiều mức độ chú ý. Tôi muốn định nghĩa hàm parse_file()là hàm lớp như dưới đây:

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

Tất nhiên mã này không hoạt động vì hàm parse_file()không nằm trong phạm vi của __init__hàm. Có cách nào để gọi một hàm lớp từ bên trong __init__lớp đó không? Hay tôi đang nghĩ về điều này sai cách?


Có bất kỳ lý do nào mà ví dụ mã cần năm phiên bản của "stat" không? Nó sẽ làm cho nó dễ đọc hơn nếu chỉ có một.
465b

Câu trả lời:


183

Gọi hàm theo cách này:

self.parse_file()

Bạn cũng cần xác định hàm parse_file () của mình như thế này:

def parse_file(self):

Các parse_filephương pháp này phải được liên kết với một đối tượng khi gọi nó (vì nó không phải là một phương pháp tĩnh). Điều này được thực hiện bằng cách gọi hàm trên một thể hiện của đối tượng, trong trường hợp của bạn là thể hiện self.


Đúng! Đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn!
PythonJin

33

Nếu tôi không sai, cả hai chức năng là một phần của lớp học của bạn, bạn nên sử dụng nó như thế này:

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

thay thế dòng của bạn:

parse_file() 

với:

self.parse_file()

Bạn có thể giải thích tại sao nó phải được sử dụng self.parse_file()và không parse_file()?
ivanleoncz

@paritoshsingh def parse_file(self):không nên được lồng trong __init__hàm để bạn không có đối tượng khởi tạo một phần?
donrondadon

@ivanleoncz Vì parse_file là phương thức cá thể, chúng ta cần sử dụng đối tượng tham chiếu để gọi tương tự.
Paritosh Singh

@rong Nếu mã này đáng kính và bạn không muốn cho phép đặt tệp phân tích cú pháp từ bên ngoài, vâng, nó nên được lồng vào nhau.
Paritosh Singh

12

Làm thế nào về:

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

Bằng cách này, nếu bạn có các biến được đặt tên stat1, stat2vv, tình hình đang cầu xin cho một tuple: stats = (...).

Vì vậy, hãy parse_filetrả lại một tuple và lưu trữ tuple trong self.stats.

Sau đó, ví dụ, bạn có thể truy cập những gì thường được gọi là stat3với self.stats[2].


Tôi đồng ý, tôi chỉ đặt self.stat1 thông qua self.stat5 trong đó để chỉ ra rằng có một số biến lớp mà tôi đang gán. Trong mã thực tế tôi có một giải pháp thanh lịch hơn.
PythonJin

Làm thế nào điều này nên được thay đổi nếu tôi muốn parse_filehàm là một phương thức của MyClassđối tượng. Trường hợp selfcần thiết?
n1k31t4

0

Trong parse_file, lấy selfđối số (giống như trong __init__). Nếu có bất kỳ bối cảnh nào khác mà bạn cần thì chỉ cần chuyển nó dưới dạng đối số bổ sung như bình thường.


0

Bạn phải khai báo parse_file như thế này; def parse_file(self). Tham số "tự" là một tham số ẩn trong hầu hết các ngôn ngữ, nhưng không phải trong python. Bạn phải thêm nó vào định nghĩa của tất cả các phương thức thuộc về một lớp. Sau đó, bạn có thể gọi hàm từ bất kỳ phương thức nào trong lớp bằng cách sử dụngself.parse_file

chương trình cuối cùng của bạn sẽ giống như thế này:

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

Tôi nghĩ rằng vấn đề của bạn thực sự là không có chức năng init thụt lề chính xác. Nó sẽ như thế này

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

     def parse_file():
          pass

Mã của bạn cũng vậy. Trừ khi bạn đặt công cụ @staticmethodtrang trí lên trên parse_file
rantanplan

ít nhất là thêm thiếu selftrong parse_filephương pháp của bạn .
rantanplan

Rất tiếc, đáng tiếc phải có thêm một lớp thụt vào bên dưới dòng "class MyClass ():". Tôi đã sửa nó ở trên, nhưng câu hỏi vẫn giữ nguyên.
PythonJin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.