Hàm gọi Python trong lớp


242

Tôi có mã này để tính khoảng cách giữa hai tọa độ. Hai chức năng đều trong cùng một lớp.

Tuy nhiên làm thế nào để tôi gọi hàm distToPointtrong hàm isNear?

class Coordinates:
    def distToPoint(self, p):
        """
        Use pythagoras to find distance
        (a^2 = b^2 + c^2)
        """
        ...

    def isNear(self, p):
        distToPoint(self, p)
        ...

41
thử: self.distToPoint (p)
momeara

Điều gì xảy ra nếu isNear và distToPoint đang lấy các đối số khác nhau. Vậy thì làm thế nào chúng ta có thể gọi distToPoint ở trong lớp? Bất cứ ai có thể giải thích rằng cho tôi xin vui lòng.
Raghavendra Gupta

Câu trả lời:


394

Vì đây là các hàm thành viên, hãy gọi nó là một hàm thành viên trong trường hợp , self.

def isNear(self, p):
    self.distToPoint(p)
    ...

2
Nhưng hãy cẩn thận self.foo () sẽ sử dụng thứ tự phân giải phương thức có thể phân giải thành một hàm trong một lớp khác.
Francis Davey

Điều gì xảy ra nếu chúng ta không sử dụng bản thân? và gọi trực tiếp distToPoint (p)?
Marlon Abeykoon

3
@Marlon Abeykoon cuộc tranh luận về "bản thân" sẽ bị bỏ lỡ
Pitipaty

1
Điều gì xảy ra nếu isNear và distToPoint đang lấy các đối số khác nhau. Vậy thì làm thế nào chúng ta có thể gọi distToPoint ở trong lớp? Bất cứ ai có thể giải thích rằng cho tôi xin vui lòng.
Raghavendra Gupta

46

Điều đó không hoạt động vì distToPointnằm trong lớp của bạn, vì vậy bạn cần thêm tiền tố vào tên lớp nếu bạn muốn tham chiếu đến nó, như thế này : classname.distToPoint(self, p). Bạn không nên làm như vậy, mặc dù. Một cách tốt hơn để làm điều đó là tham chiếu phương thức trực tiếp thông qua thể hiện của lớp (là đối số đầu tiên của phương thức lớp), như vậy : self.distToPoint(p).


@Aleski. Nếu đó là một phương thức chung (chung cho tất cả các trường hợp và không có bất kỳ biến cụ thể nào được tham chiếu trong phương thức), bạn có thể giải thích lý do tại sao người ta không nên sử dụng classname.distToPoint (self, p) không?
Yugmorf

2
@Yugmorf: Chỉ có một tình huống mà người ta nên sử dụng classname.distToPoint(self, p): khi bạn xác định một lớp con ghi đè distToPoint, nhưng cần gọi bản gốc. Nếu bạn đã cố gắng gọi self.distToPoint(p)như bình thường trong trường hợp đó, cuối cùng bạn sẽ gọi phương thức mà bạn vừa xác định và nhận được một đệ quy vô hạn. Nếu không ở trong một lớp, cũng chỉ có một tình huống mà bạn sử dụng classname.distToPoint(obj, p)thay vì obj.distToPoint(p): nếu obj có thể là một thể hiện của lớp con, nhưng bạn cần gọi bản gốc distToPointđược xác định (tiếp theo)
Aleksi Torhamo

1
trong classnamethay vì phiên bản ghi đè trong lớp con - nhưng lưu ý rằng đây là rất hacky và không nên được thực hiện nói chung mà không có một rất lý do chính đáng. Lưu ý rằng bạn phá vỡ tính đa hình của kiểu con khi bạn gọi một phương thức rõ ràng thông qua một lớp (trong cả hai ví dụ trên, bạn đặc biệt muốn làm điều đó). Vì vậy, trong ngắn hạn: bạn chỉ nên gọi một phương thức rõ ràng thông qua một lớp khi bạn cần phá vỡ tính đa hình của kiểu con vì một số lý do [tốt]. Nếu phương thức chưa được ghi đè, hai cách bằng nhau, nhưng self.distToPoint(p)ngắn hơn và dễ đọc hơn, (tiếp theo)
Aleksi Torhamo

Vì vậy, bạn chắc chắn vẫn nên sử dụng nó. Bây giờ, đi vào chi tiết cụ thể của câu hỏi của bạn: nếu phương thức của bạn không sử dụng bất kỳ biến đối tượng nào, có lẽ nó sẽ là một phân loại thay thế? Bạn tạo ra những thứ đó bằng cách thêm vào @classmethodtrước phương thức và sau đó bạn sẽ không lấy một thể hiện ( self) làm đối số đầu tiên nữa - thay vào đó bạn có được lớp, vì vậy bạn nên đặt tên cho đối số đầu tiên, vd. clsthay thế. Sau đó, bạn có thể gọi classmethod là thích obj.distToPoint(p)hoặc classname.distToPoint(p)(lưu ý thiếu obj). Bạn vẫn có thể nên sử dụng (tiếp theo)
Aleksi Torhamo

obj.distToPoint(p)tuy nhiên, nếu bạn chỉ có một ví dụ có liên quan trên tay, trừ khi - một lần nữa - bạn có một số lý do [tốt] để tránh sự đa hình của kiểu con, vì nói chung, lớp này cũng có thể bị ghi đè trong một lớp con. Tất nhiên, nếu bạn không có sẵn một thể hiện có liên quan , thì bằng mọi cách, bạn nên gọi một lớp đối xứng trực tiếp thông qua một lớp.
Aleksi Torhamo
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.