2011-11-15 29 views
22

Tôi muốn vượt qua một đối số mặc định để một phương pháp dụ sử dụng giá trị của một thuộc tính của dụ:Làm cách nào để chuyển giá trị đối số mặc định của một thành viên đối tượng sang một phương thức?

class C: 
    def __init__(self, format): 
     self.format = format 

    def process(self, formatting=self.format): 
     print(formatting) 

Khi cố gắng đó, tôi nhận được thông báo lỗi sau:

NameError: name 'self' is not defined 

Tôi muốn phương pháp để hành xử như thế này:

C("abc").process()  # prints "abc" 
C("abc").process("xyz") # prints "xyz" 

Vấn đề ở đây là gì, tại sao điều này không hoạt động? Và làm thế nào tôi có thể thực hiện công việc này?

+0

không sử dụng định dạng làm tên biến, vì nó được xây dựng trong chức năng trong python. – Yajushi

+0

Chỉnh sửa sai lầm của 'self' trong' phương thức xử lý ' –

Trả lời

31

Bạn thực sự không thể xác định giá trị này làm giá trị mặc định vì giá trị mặc định được đánh giá khi phương thức được xác định trước khi bất kỳ phiên bản nào tồn tại. Một cách dễ dàng công việc xung quanh là để làm một cái gì đó như thế này:

class C: 
    def __init__(self, format): 
     self.format = format 

    def process(self, formatting=None): 
     formatting = formatting if formatting is not None else self.format 
     print(formatting) 

self.format sẽ chỉ được sử dụng nếu formattingNone.


Để chứng minh quan điểm như thế nào giá trị mặc định làm việc, xem ví dụ sau:

def mk_default(): 
    print("mk_default has been called!") 

def myfun(foo=mk_default()): 
    print("myfun has been called.") 

print("about to test functions") 
myfun("testing") 
myfun("testing again") 

Và đầu ra ở đây:

mk_default has been called! 
about to test functions 
myfun has been called. 
myfun has been called. 

Chú ý cách mk_default được gọi là một lần duy nhất, và điều đó đã xảy ra trước khi chức năng được gọi!

+0

Tôi tin rằng 'mk_default' được gọi trước khi các hàm được gọi vì' foo = mk_default() 'gọi nó là do dấu ngoặc đơn. Không nên là 'foo = mk_default'? Sau đó, ví dụ của bạn có thể thay đổi thành 'myfun (" testing ")' theo sau là 'myfun()'. – gary

+0

Đây có phải là giải pháp được đề xuất không? – confused00

+2

Lưu ý rằng 'định dạng = định dạng hoặc self.format' sẽ đặt' định dạng' thành 'self.format' nếu' định dạng' là một giá trị falsey, chẳng hạn như 0. Điều này chỉ cắn tôi. Một cách an toàn hơn là gõ 'định dạng = định dạng nếu định dạng không phải là Không có gì khác self.format' hoặc tương đương. – Godsmith

6

Trong Python, tên selfkhông phải là đặc biệt. Nó chỉ là một quy ước cho tên tham số, đó là lý do tại sao có một tham số self trong __init__. (Trên thực tế, __init__ không phải là rất đặc biệt trong hai, và đặc biệt là nó không thực sự tạo ra các đối tượng ... đó là một câu chuyện dài hơn)

C("abc").process() tạo ra một trường hợp C, nhìn lên các phương pháp process trong lớp C, và gọi phương thức đó với cá thể C làm thông số đầu tiên. Vì vậy, nó sẽ kết thúc trong tham số self nếu bạn cung cấp nó.

Mặc dù bạn đã có thông số đó, tuy nhiên, bạn sẽ không được phép viết một cái gì đó như def process(self, formatting = self.formatting), vì self chưa nằm trong phạm vi mà bạn đặt giá trị mặc định. Trong Python, giá trị mặc định cho một tham số được tính khi hàm được biên dịch và "mắc kẹt" với hàm. (Đây cũng là lý do tương tự, nếu bạn sử dụng mặc định như [], danh sách đó sẽ ghi nhớ các thay đổi giữa các cuộc gọi đến hàm.)

Làm cách nào tôi có thể thực hiện công việc này?

Cách truyền thống là sử dụng None làm giá trị mặc định và kiểm tra giá trị đó và thay thế nó bên trong hàm.Bạn có thể thấy an toàn hơn một chút để tạo ra một giá trị đặc biệt cho mục đích (ví dụ object là tất cả những gì bạn cần, miễn là bạn ẩn nó để mã gọi không sử dụng cùng một cá thể) thay vì None. Dù bằng cách nào, bạn cũng nên kiểm tra giá trị này bằng is, chứ không phải ==.

+0

Giải pháp thay thế của bạn không đáp ứng được kết quả mong muốn khi sử dụng Không. –

+0

Nếu 'None' là giá trị hợp lệ cho' định dạng', thì bạn sẽ phải chọn một thứ khác, như tôi đã giải thích. –

1

"tự" cần được chuyển làm đối số đầu tiên cho bất kỳ hàm lớp nào nếu bạn muốn chúng hoạt động như các phương thức không tĩnh.

nó đề cập đến chính đối tượng. Bạn không thể chuyển "tự" làm đối số mặc định vì vị trí của nó được sửa làm đối số đầu tiên.

Trong trường hợp của bạn thay vì "định dạng = self.format" sử dụng "định dạng = None" và sau đó gán giá trị từ mã như sau:

[EDIT]

class c: 
     def __init__(self, cformat): 
      self.cformat = cformat 

     def process(self, formatting=None): 
      print "Formating---",formatting 
      if formatting == None: 
       formatting = self.cformat 
       print formatting 
       return formatting 
      else: 
       print formatting 
       return formatting 

c("abc").process()   # prints "abc" 
c("abc").process("xyz")  # prints "xyz" 

Lưu ý: không sử dụng "định dạng" dưới dạng tên biến, bởi vì nó được xây dựng trong chức năng trong python

+0

Vâng, tôi đã sửa lỗi 'self'. Nhưng câu trả lời của bạn không đáp ứng được kết quả mong muốn. –

+0

kiểm tra khối đã chỉnh sửa, nó sẽ giúp bạn. – Yajushi

Các vấn đề liên quan