Hãy xem ví dụ này về mẫu chiến lược bằng Python (được điều chỉnh từ ví dụ here). Trong trường hợp này, chiến lược thay thế là một hàm.Phương thức python tự động nhận 'tự' làm đối số đầu tiên như thế nào?
class StrategyExample(object):
def __init__(self, strategy=None) :
if strategy:
self.execute = strategy
def execute(*args):
# I know that the first argument for a method
# must be 'self'. This is just for the sake of
# demonstration
print locals()
#alternate strategy is a function
def alt_strategy(*args):
print locals()
Đây là kết quả cho chiến lược mặc định.
>>> s0 = StrategyExample()
>>> print s0
<__main__.StrategyExample object at 0x100460d90>
>>> s0.execute()
{'args': (<__main__.StrategyExample object at 0x100460d90>,)}
Trong ví dụ trên s0.execute
là một phương pháp (không phải là một chức năng vani đồng bằng) và do đó số đầu tiên trong args
, như mong đợi, là self
.
Dưới đây là kết quả cho chiến lược thay thế.
>>> s1 = StrategyExample(alt_strategy)
>>> s1.execute()
{'args':()}
Trong trường hợp này s1.execute
là hàm vani thuần túy và như mong đợi, không nhận được self
. Do đó args
trống. Đợi tí! Làm sao chuyện này lại xảy ra?
Cả phương pháp và hàm đều được gọi theo cùng một kiểu. Phương thức tự động nhận được self
làm đối số đầu tiên như thế nào? Và khi một phương pháp được thay thế bằng một hàm vani đơn giản, làm thế nào để nó không phải là nhận được đối số đầu tiên là self
?
Sự khác biệt duy nhất mà tôi có thể tìm thấy là khi tôi kiểm tra các thuộc tính của chiến lược mặc định và chiến lược thay thế.
>>> print dir(s0.execute)
['__cmp__', '__func__', '__self__', ...]
>>> print dir(s1.execute)
# does not have __self__ attribute
Liệu sự hiện diện của __self__
thuộc tính trên s0.execute
(phương pháp), nhưng thiếu nó trên s1.execute
(chức năng) bằng cách nào đó giải thích cho sự khác biệt này trong hành vi? Làm thế nào để tất cả điều này làm việc trong nội bộ?
Bạn có thể nghĩ của 'instance.method (arg)' như một cách viết tắt cho 'InstanceClass.method (Ví dụ , arg) '. Python cố gắng giữ cho mọi thứ đơn giản và rõ ràng nhất có thể, và tôi thấy đây là cách "minh bạch" để truy cập cá thể gọi là hàm –