2010-01-02 1 views
61
class a(object): 
    data={'a':'aaa','b':'bbb','c':'ccc'} 
    def pop(self, key, *args): 
      return self.data.pop(key, *args)#what is this mean. 

b=a() 
print b.pop('a',{'b':'bbb'}) 
print b.data 

self.data.pop(key, *args) ← ------ tại sao có đối số thứ hai?Trong Python, dict.pop (a, b) có nghĩa là gì?

+5

Hoặc nếu bạn thực sự lười biếng 'giúp đỡ (b.data.pop) 'trong REPL. –

Trả lời

84

Phương pháp pop của dicts (như self.data, tức là {'a':'aaa','b':'bbb','c':'ccc'}, đây) nhận hai đối số - xem the docs

Đối số thứ hai, default, là những gì pop trả về nếu đối số đầu tiên, key, không có. (Nếu bạn gọi pop chỉ với một đối số, key, nó sẽ đặt ra một ngoại lệ nếu khóa đó vắng mặt).

Trong ví dụ của bạn, print b.pop('a',{'b':'bbb'}), điều này là không thích hợp vì 'a' một chìa khóa trong b.data. Nhưng nếu bạn lặp lại dòng đó ...:

b=a() 
print b.pop('a',{'b':'bbb'}) 
print b.pop('a',{'b':'bbb'}) 
print b.data 

bạn sẽ thấy nó làm cho một sự khác biệt: các pop đầu tiên loại bỏ phím 'a', vì vậy trong lần thứ hai pop lập luận default được thực sự trả lại (kể từ 'a' tại là vắng mặt từ b.data).

+1

Chỉ là một chú thích nhỏ nhỏ mà tôi nghĩ rằng nó quan trọng trong một số tình huống mà người dùng cần 'pop' một phần tử' dict' nhưng giữ nguyên giá trị của phần tử xuất hiện. Vì vậy, 'dict.pop (key) 'loại bỏ' khóa' cùng với 'giá trị' liên kết nhưng cũng trả về 'giá trị' của' khóa' vừa được xóa. Tôi thấy nó hữu ích ... – flamenco

5
def func(*args): 
    pass 

Khi bạn xác định hàm theo cách này, *args sẽ là mảng đối số được truyền cho hàm. Điều này cho phép chức năng của bạn hoạt động mà không biết trước bao nhiêu đối số sẽ được truyền cho nó.

Bạn làm điều này với các đối số từ khóa quá, sử dụng **kwargs:

def func2(**kwargs): 
    pass 

Xem: Arbitrary argument lists


Trong trường hợp của bạn, bạn đã xác định một lớp mà là hành động như một cuốn từ điển. Phương pháp dict.pop được định nghĩa là pop(key[, default]).

Phương pháp của bạn không sử dụng thông số default. Tuy nhiên, bằng cách xác định phương thức của bạn với *args và chuyển qua *args đến dict.pop(), bạn cho phép người gọi sử dụng thông số default.

Nói cách khác, bạn sẽ có thể sử dụng phương pháp pop của lớp học của bạn như dict.pop:

my_a = a() 
value1 = my_a.pop('key1')  # throw an exception if key1 isn't in the dict 
value2 = my_a.pop('key2', None) # return None if key2 isn't in the dict 
21

Có quá nhiều câu hỏi ở đây. Tôi thấy ít nhất hai, có thể ba:

  • Pop (a, b) làm gì?/Tại sao có đối số thứ hai?
  • *args được sử dụng để làm gì?

Câu hỏi đầu tiên được trivially trả lời trong Python Standard Library tham khảo:

pop (key [, mặc định])

Nếu khóa có trong từ điển, loại bỏ nó và trở về của nó giá trị, khác trả về mặc định. Nếu mặc định không được đưa ra và khóa không có trong từ điển, một KeyError được nâng lên.


Câu hỏi thứ hai được bao phủ trong Python Language Reference:

Nếu hình thức “* định danh” là hiện tại, nó được khởi tạo một tuple nhận bất kỳ tham số vị trí dư thừa, mặc định vào bộ trống. Nếu có biểu mẫu “** số nhận dạng”, thì được khởi tạo từ điển mới nhận bất kỳ từ khóa dư thừa nào đối số, mặc định là một từ mới trống .

Nói cách khác, hàm pop có ít nhất hai đối số. Hai cái đầu tiên được gán tên selfkey; và phần còn lại được nhồi vào một tuple gọi là args.

Điều gì đang xảy ra trên dòng tiếp theo khi *args được chuyển đi trong cuộc gọi đến self.data.pop là nghịch đảo của điều này - bộ tóan *args được mở rộng đến các thông số vị trí được chuyển. Này được giải thích trong Python Language Reference:

Nếu cú ​​pháp * biểu hiện xuất hiện trong cuộc gọi chức năng, biểu hiện phải đánh giá để một chuỗi. Các yếu tố từ chuỗi này được đối xử như thể họ là thêm đối số vị trí

Nói tóm lại, a.pop() muốn trở thành linh hoạt và chấp nhận bất kỳ số lượng tham số vị trí, do đó nó có thể vượt qua số lượng không rõ này của tham số vị trí trên để self.data.pop().

Điều này mang đến cho bạn sự linh hoạt; data xảy ra là dict ngay bây giờ và do đó self.data.pop() có một hoặc hai thông số; nhưng nếu bạn đã thay đổi data thành loại mất 19 tham số cho một cuộc gọi đến self.data.pop(), bạn sẽ không phải thay đổi lớp học a chút nào. Bạn vẫn sẽ phải thay đổi bất kỳ mã nào được gọi là a.pop() để vượt qua 19 thông số cần thiết.

+1

+1 cho nỗ lực. Tôi sợ rằng tiếng Anh của OP không phải là nhiệm vụ đọc câu trả lời của bạn. – bernie

+0

Tôi đã viết rằng trước khi tôi đọc tiểu sử OP. Bây giờ tôi đã đọc tiểu sử nói và thấy một số câu hỏi khác của OP. Tôi vừa thực hiện một nỗ lực khác, lần này chỉ sử dụng mã :) –

5
>>> def func(a, *args, **kwargs): 
... print 'a %s, args %s, kwargs %s' % (a, args, kwargs) 
... 
>>> func('one', 'two', 'three', four='four', five='five') 
a one, args ('two', 'three'), kwargs {'four': 'four', 'five': 'five'} 

>>> def anotherfunct(beta, *args): 
... print 'beta %s, args %s' % (beta, args) 
... 
>>> def func(a, *args, **kwargs): 
... anotherfunct(a, *args) 
... 
>>> func('one', 'two', 'three', four='four', five='five') 
beta one, args ('two', 'three') 
>>> 
+0

bạn có đọc được câu hỏi này không? – SilentGhost

+1

Tôi đọc một số câu hỏi, như được nêu chi tiết trong câu trả lời khác của tôi. Tôi cũng đọc hồ sơ OPs và nhận ra rằng câu trả lời khác của tôi là vô dụng. Câu trả lời này nên chứng minh ít nhất một phần của những gì * args làm, đó là những gì tôi đoán sự nhầm lẫn thực sự OP là, mặc dù chủ đề. –

+0

@James, +1 cho nỗ lực thêm. Tôi đã đạt được kết luận tương tự về câu hỏi thực sự. –