Hướng dẫn calling class method from static method python - gọi phương thức lớp từ phương thức tĩnh python

Nó hoàn toàn có thể, nhưng không có ý nghĩa lắm. Suy ngự lớp sau:

class MyClass:
    # Normal method:
    def normal_method(self, data):
        print "Normal method called with instance %s and data %s" % (self, data)

    @classmethod
    def class_method(cls, data):
        print "Class method called with class %s and data %s" % (cls, data)

    @staticmethod
    def static_method(data):
        print "Static method called with data %s" % (data)

Rõ ràng, chúng ta có thể gọi điều này theo những cách dự kiến:

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!

Nhưng cũng xem xét điều này:

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

Cú pháp

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
8 khá nhiều chỉ là một "phím tắt" cho
>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
9. Đó là lý do tại sao có tham số "bản thân" này trong các phương pháp, để vượt qua bản thân. Tên bản thân không phải là phép thuật, bạn có thể gọi nó là bất cứ điều gì bạn muốn.

Các thủ thuật tương tự là hoàn toàn có thể từ việc đưa ra một phương pháp tĩnh. Bạn có thể gọi phương thức bình thường với một thể hiện là tham số đầu tiên, như vậy:

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!

Vì vậy, câu trả lời là có, bạn có thể cal phương thức không tĩnh từ các phương thức tĩnh. Nhưng chỉ khi bạn có thể vượt qua trong một trường hợp như tham số đầu tiên. Vì vậy, bạn phải tạo nó từ bên trong phương thức tĩnh (và trong trường hợp đó, bạn có thể tốt hơn với một phương thức lớp) hoặc chuyển nó vào. Nhưng nếu bạn vượt qua trong trường hợp, bạn thường có thể biến nó thành một phương thức bình thường.

Vì vậy, bạn có thể, nhưng, nó khá vô nghĩa.

Và điều đó sau đó đặt ra câu hỏi: Tại sao bạn muốn?

Trong hướng dẫn này, tôi sẽ giúp làm sáng tỏ những gì đằng sau các phương thức lớp, phương pháp tĩnh và phương pháp thể hiện thông thường.

Nếu bạn phát triển sự hiểu biết trực quan về sự khác biệt của họ, bạn sẽ có thể viết Python hướng đối tượng để truyền đạt ý định của nó rõ ràng hơn và sẽ dễ dàng duy trì hơn trong thời gian dài.

Ví dụ, lớp và phương thức tĩnh - tổng quan

Hãy bắt đầu bằng cách viết một lớp (Python 3) chứa các ví dụ đơn giản cho cả ba loại phương thức:

class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'

Lưu ý: Đối với người dùng Python 2: Các nhà trang trí

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
0 và
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
1 có sẵn như Python 2.4 và ví dụ này sẽ hoạt động như hiện tại. Thay vì sử dụng tuyên bố đơn giản
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
2, bạn có thể chọn khai báo một lớp mới kế thừa từ
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
3 với cú pháp
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
4. Ngoài ra, bạn rất tốt để đi.
For Python 2 users: The
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
0 and
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
1 decorators are available as of Python 2.4 and this example will work as is. Instead of using a plain
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
2 declaration you might choose to declare a new-style class inheriting from
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
3 with the
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
4 syntax. Other than that you’re good to go.

Phương pháp thể hiện

Phương pháp đầu tiên trên

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
5, được gọi là
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
6, là một phương thức thể hiện thông thường. Đó là loại phương pháp cơ bản, không rườm rà mà bạn sẽ sử dụng hầu hết thời gian. Bạn có thể thấy phương thức lấy một tham số,
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7, chỉ ra một thể hiện là
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
5 khi phương thức được gọi (nhưng tất nhiên các phương thức thể hiện có thể chấp nhận nhiều hơn chỉ một tham số).

Thông qua tham số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7, các phương thức thể hiện có thể tự do truy cập các thuộc tính và các phương thức khác trên cùng một đối tượng. Điều này mang lại cho họ rất nhiều sức mạnh khi sửa đổi trạng thái đối tượng.

Họ không chỉ có thể sửa đổi trạng thái đối tượng, các phương thức thể hiện cũng có thể truy cập vào chính lớp thông qua thuộc tính

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
0. Điều này có nghĩa là các phương thức thể hiện cũng có thể sửa đổi trạng thái lớp.

Phương pháp lớp

Hãy để so sánh điều đó với phương pháp thứ hai,

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
1. Tôi đã đánh dấu phương pháp này với một bộ trang trí
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
1 để gắn cờ nó như một phương pháp lớp.

Thay vì chấp nhận tham số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7, các phương thức lớp lấy tham số
    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
4 trỏ đến lớp và không phải là thể hiện đối tượng khi phương thức được gọi.

Vì phương thức lớp chỉ có quyền truy cập vào đối số

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
4 này, nên nó có thể sửa đổi trạng thái thể hiện đối tượng. Điều đó sẽ yêu cầu truy cập vào
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7. Tuy nhiên, các phương thức lớp vẫn có thể sửa đổi trạng thái lớp áp dụng trên tất cả các trường hợp của lớp.

Phương pháp tĩnh

Phương pháp thứ ba,

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
7 được đánh dấu bằng một bộ trang trí
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
0 để gắn cờ nó như một phương pháp tĩnh.

Loại phương thức này không lấy tham số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 cũng như
    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
4 (nhưng tất nhiên là nó miễn phí chấp nhận một số lượng tùy ý các tham số khác).

Do đó, một phương pháp tĩnh không thể sửa đổi trạng thái đối tượng cũng như trạng thái lớp. Các phương thức tĩnh bị hạn chế trong những dữ liệu mà họ có thể truy cập - và chúng chủ yếu là một cách để đặt tên cho các phương thức của bạn.

Hãy cùng xem họ trong hành động!

Tôi biết cuộc thảo luận này đã được lý thuyết khá cho đến thời điểm này. Và tôi tin rằng điều quan trọng là bạn phát triển sự hiểu biết trực quan về cách các loại phương pháp này khác nhau trong thực tế. Bây giờ chúng tôi sẽ đi qua một số ví dụ cụ thể.

Hãy cùng xem cách các phương pháp này hoạt động như thế nào khi chúng ta gọi chúng. Chúng tôi sẽ bắt đầu bằng cách tạo một thể hiện của lớp và sau đó gọi ba phương thức khác nhau trên đó.

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
5 được thiết lập theo cách mà mỗi phương thức triển khai trả về một bộ chứa thông tin để chúng tôi theo dõi những gì mà diễn ra - và phần nào của lớp hoặc đối tượng mà phương thức có thể truy cập.

Ở đây, những gì xảy ra khi chúng ta gọi một phương thức thể hiện:instance method:

>>>

>>> obj = MyClass()
>>> obj.method()
('instance method called', <MyClass instance at 0x10205d190>)

Điều này xác nhận rằng

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
6 (phương thức thể hiện) có quyền truy cập vào thể hiện đối tượng (được in là
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
3) thông qua đối số
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7.

Khi phương thức được gọi, Python thay thế đối số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 bằng đối tượng phiên bản,
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
6. Chúng ta có thể bỏ qua đường cú pháp của cú pháp cuộc gọi chấm (
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
7) và truyền đối tượng thể hiện theo cách thủ công để có được kết quả tương tự:

>>>

>>> MyClass.method(obj)
('instance method called', <MyClass instance at 0x10205d190>)

Điều này xác nhận rằng

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
6 (phương thức thể hiện) có quyền truy cập vào thể hiện đối tượng (được in là
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
3) thông qua đối số
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7.

Khi phương thức được gọi, Python thay thế đối số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 bằng đối tượng phiên bản,
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
6. Chúng ta có thể bỏ qua đường cú pháp của cú pháp cuộc gọi chấm (
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
7) và truyền đối tượng thể hiện theo cách thủ công để có được kết quả tương tự:

Bạn có thể đoán điều gì sẽ xảy ra nếu bạn cố gắng gọi phương thức mà không tạo ra một thể hiện trước không?class method next:

>>>

>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)

Điều này xác nhận rằng

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
6 (phương thức thể hiện) có quyền truy cập vào thể hiện đối tượng (được in là
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
3) thông qua đối số
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7.

Khi phương thức được gọi, Python thay thế đối số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 bằng đối tượng phiên bản,
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
6. Chúng ta có thể bỏ qua đường cú pháp của cú pháp cuộc gọi chấm (
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
7) và truyền đối tượng thể hiện theo cách thủ công để có được kết quả tương tự:

Bạn có thể đoán điều gì sẽ xảy ra nếu bạn cố gắng gọi phương thức mà không tạo ra một thể hiện trước không?

Nhân tiện, các phương thức thể hiện cũng có thể truy cập vào bản thân lớp thông qua thuộc tính

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
0. Điều này làm cho các phương thức thể hiện mạnh mẽ về các hạn chế truy cập - chúng có thể sửa đổi trạng thái trên thể hiện đối tượng và trên chính lớp.static method now:

>>>

>>> obj.staticmethod()
'static method called'

Điều này xác nhận rằng

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
6 (phương thức thể hiện) có quyền truy cập vào thể hiện đối tượng (được in là
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
3) thông qua đối số
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7.

Khi phương thức được gọi, Python thay thế đối số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 bằng đối tượng phiên bản,
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
6. Chúng ta có thể bỏ qua đường cú pháp của cú pháp cuộc gọi chấm (
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
7) và truyền đối tượng thể hiện theo cách thủ công để có được kết quả tương tự:

Bạn có thể đoán điều gì sẽ xảy ra nếu bạn cố gắng gọi phương thức mà không tạo ra một thể hiện trước không?

Nhân tiện, các phương thức thể hiện cũng có thể truy cập vào bản thân lớp thông qua thuộc tính

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
0. Điều này làm cho các phương thức thể hiện mạnh mẽ về các hạn chế truy cập - chúng có thể sửa đổi trạng thái trên thể hiện đối tượng và trên chính lớp.

>>>

>>> MyClass.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)

>>> MyClass.staticmethod()
'static method called'

>>> MyClass.method()
TypeError: unbound method method() must
    be called with MyClass instance as first
    argument (got nothing instead)

Điều này xác nhận rằng

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
6 (phương thức thể hiện) có quyền truy cập vào thể hiện đối tượng (được in là
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
3) thông qua đối số
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7.

Khi phương thức được gọi, Python thay thế đối số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 bằng đối tượng phiên bản,
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
6. Chúng ta có thể bỏ qua đường cú pháp của cú pháp cuộc gọi chấm (
class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
7) và truyền đối tượng thể hiện theo cách thủ công để có được kết quả tương tự:

Bạn có thể đoán điều gì sẽ xảy ra nếu bạn cố gắng gọi phương thức mà không tạo ra một thể hiện trước không?

Nhân tiện, các phương thức thể hiện cũng có thể truy cập vào bản thân lớp thông qua thuộc tính

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
0. Điều này làm cho các phương thức thể hiện mạnh mẽ về các hạn chế truy cập - chúng có thể sửa đổi trạng thái trên thể hiện đối tượng và trên chính lớp.

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
0

>>>

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
1

Hãy cùng thử phương pháp lớp tiếp theo: This code example and the ones further along in the tutorial use Python 3.6 f-strings to construct the string returned by

>>> MyClass.method(obj)
('instance method called', <MyClass instance at 0x10205d190>)
7. On Python 2 and versions of Python 3 before 3.6 you’d use a different string formatting expression, for example:

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
2

Gọi class MyClass: def method(self): return 'instance method called', self @classmethod def classmethod(cls): return 'class method called', cls @staticmethod def staticmethod(): return 'static method called' 9 cho chúng tôi thấy rằng nó không có quyền truy cập vào đối tượng class MyClass: def method(self): return 'instance method called', self @classmethod def classmethod(cls): return 'class method called', cls @staticmethod def staticmethod(): return 'static method called' 3, nhưng chỉ với đối tượng >>> obj = MyClass() >>> obj.method() ('instance method called', <MyClass instance at 0x10205d190>) 1, đại diện cho bản thân lớp (mọi thứ trong Python là một đối tượng, thậm chí cả các lớp).

Lưu ý cách Python tự động chuyển lớp là đối số đầu tiên cho hàm khi chúng ta gọi

>>> obj = MyClass()
>>> obj.method()
('instance method called', <MyClass instance at 0x10205d190>)
2. Gọi một phương thức trong Python thông qua cú pháp DOT kích hoạt hành vi này. Tham số
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 trên các phương thức ví dụ hoạt động theo cùng một cách.

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
3

Xin lưu ý rằng việc đặt tên cho các tham số này

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 và
    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
4 chỉ là một quy ước. Bạn có thể dễ dàng đặt tên cho chúng
>>> obj = MyClass()
>>> obj.method()
('instance method called', <MyClass instance at 0x10205d190>)
6 và
>>> obj = MyClass()
>>> obj.method()
('instance method called', <MyClass instance at 0x10205d190>)
7 và nhận được kết quả tương tự. Tất cả những gì quan trọng là họ đã định vị đầu tiên trong danh sách tham số cho phương thức.

Thời gian để gọi phương thức tĩnh ngay bây giờ:

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
4

Bạn có thấy cách chúng tôi gọi

>>> obj = MyClass()
>>> obj.method()
('instance method called', <MyClass instance at 0x10205d190>)
8 trên đối tượng và có thể làm như vậy thành công không? Một số nhà phát triển ngạc nhiên khi họ biết rằng nó có thể gọi một phương thức tĩnh trên một thể hiện đối tượng.

Đằng sau hậu trường, Python chỉ đơn giản thực thi các hạn chế truy cập bằng cách không truyền trong đối số

>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7 hoặc
    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
4 khi một phương thức tĩnh được gọi bằng cú pháp DOT.

Điều này xác nhận rằng các phương thức tĩnh không thể truy cập trạng thái thể hiện đối tượng cũng như trạng thái lớp. Chúng hoạt động như các chức năng thông thường nhưng thuộc về lớp học (và mọi trường hợp) không gian tên.

>>>

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
5

Như bạn có thể thấy, chúng ta có thể sử dụng các chức năng của nhà máy để tạo các đối tượng

>>> MyClass.method(obj)
('instance method called', <MyClass instance at 0x10205d190>)
6 mới được cấu hình theo cách chúng ta muốn. Tất cả đều sử dụng cùng một hàm tạo
>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)
5 trong nội bộ và chỉ cần cung cấp một lối tắt để ghi nhớ tất cả các thành phần khác nhau.

Một cách khác để xem xét việc sử dụng các phương thức lớp này là chúng cho phép bạn xác định các hàm tạo thay thế cho các lớp của bạn.

Python chỉ cho phép một phương thức

>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)
5 cho mỗi lớp. Sử dụng các phương thức lớp, nó có thể thêm nhiều hàm tạo thay thế khi cần thiết. Điều này có thể làm cho giao diện cho các lớp học của bạn tự ghi chép (ở một mức độ nhất định) và đơn giản hóa việc sử dụng của chúng.

Khi nào nên sử dụng các phương thức tĩnh

Nó khó khăn hơn một chút để đưa ra một ví dụ điển hình ở đây. Nhưng hãy nói với bạn những gì, tôi sẽ tiếp tục kéo dài pizza tương tự mỏng hơn và mỏng hơn (yum!)

Ở đây, những gì tôi đã nghĩ ra:

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
6

Bây giờ tôi đã thay đổi gì ở đây? Đầu tiên, tôi đã sửa đổi hàm tạo và

>>> MyClass.method(obj)
('instance method called', <MyClass instance at 0x10205d190>)
7 để chấp nhận một đối số
>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)
8 bổ sung.

Tôi cũng đã thêm một phương thức ví dụ

>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)
9 tính toán và trả về khu vực pizza pizza (đây cũng sẽ là một ứng cử viên tốt cho
>>> obj.staticmethod()
'static method called'
0 - ​​nhưng này, đây chỉ là một ví dụ đồ chơi).

Thay vì tính toán diện tích trực tiếp trong

>>> obj.classmethod()
('class method called', <class MyClass at 0x101a2f4c8>)
9, sử dụng công thức khu vực vòng tròn nổi tiếng, tôi đã đưa ra một phương pháp tĩnh
>>> obj.staticmethod()
'static method called'
2 riêng biệt.

Hãy để thử nó ra!

>>>

>>> instance = MyClass()
>>> instance.normal_method("Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!

>>> instance.class_method("Success!")
Class method called with class __main__.MyClass and data Success!

>>> instance.static_method("Success!")
Static method called with data Success!
7

Chắc chắn, đây là một chút của một ví dụ đơn giản, nhưng nó sẽ không để giải thích một số lợi ích mà các phương pháp tĩnh mang lại.

Như chúng tôi đã học, các phương pháp tĩnh có thể truy cập vào lớp hoặc trạng thái thể hiện vì họ không có đối số

    @staticmethod
    def a_cool_static_method(instance, data):
        print "Cool method called with instance %s and data %s" % (instance, data)
        MyClass.normal_method(instance, data)
        MyClass.class_method(data)
        MyClass.static_method(data)

>>> instance.a_cool_static_method(instance, "So Cool!")
Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
Class method called with class __main__.MyClass and data So Cool!
Static method called with data So Cool!
4 hoặc
>>> MyClass.normal_method(instance, "Success!")
Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
7. Đó là một hạn chế lớn - nhưng nó cũng là một tín hiệu tuyệt vời để cho thấy một phương pháp cụ thể độc lập với mọi thứ khác xung quanh nó.

Trong ví dụ trên, nó rõ ràng rằng

>>> obj.staticmethod()
'static method called'
2 có thể sửa đổi lớp hoặc thể hiện lớp theo bất kỳ cách nào. (Chắc chắn, bạn luôn có thể làm việc xung quanh điều đó với một biến toàn cầu nhưng đó không phải là vấn đề ở đây.)

Bây giờ, tại sao điều đó lại hữu ích?

Việc gắn cờ một phương thức như một phương pháp tĩnh không chỉ là một gợi ý rằng một phương thức đã giành được sửa đổi lớp hoặc trạng thái thể hiện - hạn chế này cũng được thực thi bởi thời gian chạy Python.

Các kỹ thuật như thế cho phép bạn giao tiếp rõ ràng về các phần của kiến ​​trúc lớp của bạn để công việc phát triển mới được hướng dẫn một cách tự nhiên để xảy ra trong các ranh giới đã đặt ra này. Tất nhiên, nó sẽ đủ dễ dàng để thách thức những hạn chế này. Nhưng trong thực tế, họ thường giúp tránh các sửa đổi tình cờ đi ngược lại với thiết kế ban đầu.

Nói cách khác, sử dụng các phương thức tĩnh và phương pháp lớp là cách để truyền đạt ý định của nhà phát triển trong khi thực thi ý định đó đủ để tránh hầu hết các lỗi và lỗi của tâm trí sẽ phá vỡ thiết kế.

Áp dụng một cách tiết kiệm và khi nó có ý nghĩa, viết một số phương pháp của bạn theo cách có thể cung cấp lợi ích bảo trì và làm cho ít có khả năng các nhà phát triển khác sử dụng các lớp của bạn không chính xác.

Phương pháp tĩnh cũng có lợi ích khi viết mã kiểm tra.

Bởi vì phương pháp

>>> obj.staticmethod()
'static method called'
2 hoàn toàn độc lập với phần còn lại của lớp, nó dễ dàng hơn nhiều để kiểm tra.

Chúng tôi không phải lo lắng về việc thiết lập một thể hiện lớp hoàn chỉnh trước khi chúng tôi có thể kiểm tra phương thức trong một bài kiểm tra đơn vị. Chúng ta chỉ có thể bắn đi như chúng ta sẽ thử nghiệm một chức năng thông thường. Một lần nữa, điều này làm cho việc bảo trì trong tương lai dễ dàng hơn.

Key Takeaways

  • Các phương thức thể hiện cần một thể hiện lớp và có thể truy cập phiên bản thông qua
    >>> MyClass.normal_method(instance, "Success!")
    Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
    
    7.
  • Phương pháp lớp don don cần một thể hiện lớp. Họ có thể truy cập vào trường hợp (
    >>> MyClass.normal_method(instance, "Success!")
    Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
    
    7) nhưng họ có quyền truy cập vào lớp thông qua
        @staticmethod
        def a_cool_static_method(instance, data):
            print "Cool method called with instance %s and data %s" % (instance, data)
            MyClass.normal_method(instance, data)
            MyClass.class_method(data)
            MyClass.static_method(data)
    
    >>> instance.a_cool_static_method(instance, "So Cool!")
    Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
    Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
    Class method called with class __main__.MyClass and data So Cool!
    Static method called with data So Cool!
    
    4.
  • Các phương pháp tĩnh don lồng có quyền truy cập vào
        @staticmethod
        def a_cool_static_method(instance, data):
            print "Cool method called with instance %s and data %s" % (instance, data)
            MyClass.normal_method(instance, data)
            MyClass.class_method(data)
            MyClass.static_method(data)
    
    >>> instance.a_cool_static_method(instance, "So Cool!")
    Cool method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
    Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data So Cool!
    Class method called with class __main__.MyClass and data So Cool!
    Static method called with data So Cool!
    
    4 hoặc
    >>> MyClass.normal_method(instance, "Success!")
    Normal method called with instance <__main__.MyClass instance at 0xb7d26bcc> and data Success!
    
    7. Chúng hoạt động như các chức năng thông thường nhưng thuộc về không gian tên lớp.
  • Phương pháp tĩnh và lớp giao tiếp và (ở một mức độ nhất định) thực thi ý định của nhà phát triển về thiết kế lớp. Điều này có thể có lợi ích bảo trì.

Phương pháp tĩnh có thể gọi một phương thức lớp python không?

Một phương thức tĩnh không có quyền truy cập vào các biến lớp và phiên bản vì nó không nhận được đối số đầu tiên ngầm như bản thân và CLS.Do đó, nó không thể sửa đổi trạng thái của đối tượng hoặc lớp.Phương thức lớp có thể được gọi bằng cách sử dụng className.method_name () cũng như bằng cách sử dụng một đối tượng của lớp.The class method can be called using ClassName. method_name() as well as by using an object of the class.

Chúng ta có thể gọi phương thức tĩnh từ phương thức không tĩnh trong python không?

Phương pháp tĩnh được gọi với dữ liệu rất tuyệt!Vì vậy, câu trả lời là có, bạn có thể cal phương thức không tĩnh từ các phương thức tĩnh.Nhưng chỉ khi bạn có thể vượt qua trong một trường hợp như tham số đầu tiên.Vì vậy, bạn hoặc phải tạo nó từ bên trong phương thức tĩnh (và trong trường hợp đó, bạn có thể tốt hơn với một phương thức lớp) hoặc chuyển nó vào.

Bạn có thể gọi phương thức lớp cơ sở mà không cần tạo một thể hiện trong Python không?

Phương thức tĩnh có thể được gọi mà không tạo ra một đối tượng hoặc thể hiện.Chỉ cần tạo phương thức và gọi nó trực tiếp.Đây là theo nghĩa trực giao để lập trình định hướng đối tượng: Chúng tôi gọi một phương thức mà không tạo các đối tượng.. Simply create the method and call it directly. This is in a sense orthogonal to object orientated programming: we call a method without creating objects.