Phương thức tĩnh - Làm thế nào để gọi một phương thức từ một phương thức khác?


95

Khi tôi có các phương thức thông thường để gọi một phương thức khác trong một lớp, tôi phải làm điều này

class test:
    def __init__(self):
        pass
    def dosomething(self):
        print "do something"
        self.dosomethingelse()
    def dosomethingelse(self):
        print "do something else"

nhưng khi tôi có các phương thức tĩnh, tôi không thể viết

self.dosomethingelse()

bởi vì không có trường hợp. Tôi phải làm thế nào trong Python để gọi một phương thức tĩnh từ một phương thức tĩnh khác của cùng một lớp?

Chỉnh sửa: thật là một mớ hỗn độn. Ok, tôi đã sửa câu hỏi trở lại câu hỏi ban đầu. Tôi đã có câu trả lời cho câu hỏi thứ hai trong bình luận của Peter Hansen. Nếu bạn nghĩ tôi nên mở một câu hỏi khác cho câu trả lời mà tôi đã có, hãy cho tôi biết.


3
@pablo: bạn không thể thay đổi bản chất của câu hỏi !! Kết thúc câu hỏi này và bắt đầu câu hỏi khác !!
jldupont

Ừ ừ. ý bạn là xóa câu hỏi? Câu trả lời đã có trong bình luận của Peter Hansen
Pablo

@pablo: bạn không thể xóa ở đây điều này sẽ không lịch sự đối với tất cả những người đã đóng góp câu trả lời cho câu hỏi của bạn. Bạn cần chấp nhận một câu trả lời tạo một câu hỏi mới.
jldupont

1
@pablo: và chỉ cần nói rõ: câu trả lời phải được chấp nhận cho công thức câu hỏi ban đầu của bạn . Đừng lo lắng, bạn sẽ học theo cách của mình ở đây. Chúc mừng :-)
jldupont

Câu trả lời:


77

class.method nên làm việc.

class SomeClass:
  @classmethod
  def some_class_method(cls):
    pass

  @staticmethod
  def some_static_method():
    pass

SomeClass.some_class_method()
SomeClass.some_static_method()

16
Lời khuyên nên được bổ sung ở đây: Rõ ràng là các classmethods không có nhược điểm nào so với staticmethods và classmethods cho phép phương thức này được mở rộng trong tương lai để gọi các phương thức lớp khác. Vì vậy, nó nên luôn được ưu tiên, mặc dù không có nhu cầu ngay lập tức.
u0b34a0f6ae

1
@ u0b34a0f6ae: Tôi không biết liệu tôi có đang làm điều gì đó tốt hay không ... nhưng tôi đã xác định một decorator bên trong một lớp. Người trang trí phải là "staticmethod", không phải là "classmethod".
André Caldas

@ u0b34a0f6ae Mặc dù vậy, classmethods có luôn luôn an toàn không? Trong trường hợp sử dụng của tôi, tôi đang sử dụng staticmethods trong các luồng để ngăn truy cập tình cờ vào lớp có thể không an toàn cho luồng.
aquavitae

@ u0b34a0f6ae luôn mạnh tay một chút. Ví dụ sử dụng PySpark staticmethods có thể được sử dụng trong các công việc rdd và classmethods không thể.
Laurens Koppenol

134

Tôi phải làm thế nào trong Python để gọi một phương thức tĩnh từ một phương thức tĩnh khác của cùng một lớp?

class Test() :
    @staticmethod
    def static_method_to_call()
        pass

    @staticmethod
    def another_static_method() :
        Test.static_method_to_call()

    @classmethod
    def another_class_method(cls) :
        cls.static_method_to_call()

Lời gọi Test.static_method_to_call()cũng sẽ hoạt động từ các phương thức non-static và non-class khác của lớp này, phải không? (... và có lẽ cả các lớp khác?)
gr4nt3d

Có, Test.static_method_to_call()sẽ hoạt động từ bất cứ đâu.
warvariuc

11

LƯU Ý - có vẻ như câu hỏi đã thay đổi một số. Câu trả lời cho câu hỏi về cách bạn gọi một phương thức thể hiện từ một phương thức tĩnh là bạn không thể không chuyển một thể hiện vào làm đối số hoặc khởi tạo thể hiện đó bên trong phương thức tĩnh.

Phần sau phần lớn là để trả lời "cách bạn gọi một phương thức tĩnh từ một phương thức tĩnh khác":

Gấu nhớ rằng có một sự khác biệt giữa các phương pháp tĩnh và phương pháp lớp trong Python. Một phương thức tĩnh không có đối số đầu tiên ngầm định, trong khi phương thức lớp lấy lớp làm đối số đầu tiên ngầm định (thường clstheo quy ước). Với ý nghĩ đó, đây là cách bạn sẽ làm điều đó:

Nếu đó là một phương thức tĩnh:

test.dosomethingelse()

Nếu đó là một phương thức lớp:

cls.dosomethingelse()

1
bạn chỉ có thể sử dụng cls.dosomethingelse()từ bên trong định nghĩa lớp.
jldupont

3
Để chính xác hơn, bạn chỉ có thể sử dụng cls.dosomethingelse()từ trong chính phương thức lớp. Giống như bạn chỉ có thể sử dụng selftừ trong chính một phương thức instance.
Jason Baker

1
xin lỗi, tôi đã viết sai câu hỏi. GIÁO SƯ!. Tôi muốn viết "Tôi phải làm như thế nào trong Python để gọi một phương thức cá thể từ một phương thức tĩnh khác của cùng một lớp" chứ không phải "Tôi phải làm như thế nào trong Python để gọi một phương thức tĩnh từ một phương thức tĩnh khác giống nhau lớp học "
Pablo

@pablo: Trong trường hợp này, bạn cần viết một câu hỏi khác và hoàn thành câu hỏi này.
jldupont

@jldupont, tôi đã có câu trả lời nhưng trong một bình luận. Tôi phải làm gì vì tôi không thể chấp nhận nó nhưng sẽ rất lãng phí nếu xóa câu hỏi, phải không?
Pablo

4

OK sự khác biệt chính giữa phương thức lớp và phương thức tĩnh là:

  • phương thức lớp có bản sắc riêng của nó, đó là lý do tại sao chúng phải được gọi từ bên trong một INSTANCE.
  • mặt khác, phương thức tĩnh có thể được chia sẻ giữa nhiều trường hợp để nó phải được gọi từ bên trong LỚP

0

bạn không thể gọi các phương thức không tĩnh từ các phương thức tĩnh nhưng bằng cách tạo một thể hiện bên trong phương thức tĩnh .... nó sẽ hoạt động như vậy

class test2(object):
    def __init__(self):
        pass

    @staticmethod
    def dosomething():
        print "do something"
        #creating an instance to be able to call dosomethingelse(),or you may use any existing instace
        a=test2()
        a.dosomethingelse()

    def dosomethingelse(self):
        print "do something else"

test2.dosomething()

hy vọng rằng sẽ giúp bạn :)


3
IMO cách tiếp cận này đáng chú ý là tệ hơn so với việc chỉ sử dụng @classmethodđể khai báo các phương thức của bạn và sử dụng cls.dosomethingelse()bên trong cls.dosomething()- tệ hơn về cả hiệu suất (khởi tạo các đối tượng chỉ để truy cập vào một phương thức tĩnh) và khả năng đọc (nó không đơn giản và tôi tưởng tượng nếu loại đó của mô hình đã trở thành soạn sẵn, toàn bộ codebase có thể trở nên khá khó khăn đối với một con người để phân tích)
Kyle hoang dã

Như tôi đã đọc ở một nơi khác tại SO, thay vì khởi tạo trực tiếp cá thể để gọi một phương thức, bạn chỉ có thể gọi nó - nó sẽ tự khởi tạo chính nó.
Nakilon

0

Nếu những điều này không phụ thuộc vào lớp hoặc cá thể thì tại sao không biến chúng thành một hàm? Vì điều này có vẻ giống như giải pháp rõ ràng. Tất nhiên trừ khi bạn nghĩ rằng nó sẽ cần được ghi đè, phân lớp, v.v. Nếu vậy thì các câu trả lời trước là lựa chọn tốt nhất. Ngón tay vượt qua Tôi sẽ không bị đánh dấu vì chỉ cung cấp một giải pháp thay thế có thể phù hợp hoặc có thể không phù hợp với nhu cầu của một số người;).

Vì câu trả lời đúng sẽ phụ thuộc vào trường hợp sử dụng của mã được đề cập;)

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.