2013-08-30 27 views
9

Chỉ cần suy nghĩ về số dict của Python "chức năng" và bắt đầu nhận ra rằng dict thực sự không phải là một chức năng. Ví dụ: nếu chúng tôi thực hiện dir(dict), chúng tôi sẽ có tất cả các loại phương pháp không được bao gồm trong không gian tên thông thường của hàm do người dùng xác định. Mở rộng suy nghĩ đó, nó tương tự như dir(list)dir(len). Chúng không hoạt động, nhưng thực sự là type s. Nhưng sau đó tôi nhầm lẫn về trang tài liệu, http://docs.python.org/2/library/functions.html, trong đó rõ ràng nói chức năng. (Tôi đoán nó thực sự chỉ nên nói callin được xây dựng)Chức năng dựng sẵn của Python không thực sự hoạt động, phải không?

Vì vậy, những gì cho? (Bắt đầu dường như phân biệt các lớp và chức năng là tầm thường)

+7

[Nếu nó trông giống như một hàm và hoạt động như một hàm, thì đó là hàm] (http://stackoverflow.com/a/4205163/489590), phải không? –

+1

Lưu ý rằng 'dir()' không bao giờ có ý định cung cấp thông tin tổng quan * đầy đủ về các chức năng có sẵn. 'dir (type)' cung cấp cho bạn rất nhiều hàm giống nhau. –

+0

Tôi đồng ý rằng các khía cạnh của điểm này hướng vào các lớp học hơn là các hàm. Sau khi tất cả các bạn có thể làm những việc như 'isinstance (x, dict)' mà không nên làm việc nếu 'dict' là một hàm thuần túy. – Alfe

Trả lời

3

Một cách mà dict là đặc biệt, so với, nói, sum, là mặc dù cả hai đều callable, và cả hai đều thực hiện trong C (trong CPython, dù sao), dict là một type; nghĩa là, isinstance(dict, type) == True. Điều này có nghĩa rằng bạn có thể sử dụng dict là lớp cơ sở cho các loại khác, bạn có thể viết:

class MyDictSubclass(dict): 
    pass 

nhưng không

class MySumSubclass(sum): 
    pass 

này có thể hữu ích để làm cho các lớp học mà cư xử gần giống như một đối tượng dựng sẵn, nhưng với một số cải tiến. Ví dụ, bạn có thể định nghĩa một lớp con của tuple mà thực hiện + như Ngoài vector thay vì nối:

class Vector(tuple): 
    def __add__(self, other): 
     return Vector(x + y for x, y in zip(self, other)) 

Mà sẽ trả về một điểm thú vị. type cũng được thực hiện trong C. Nó cũng có thể gọi được. Giống như dict (và không giống như sum), đây là phiên bản của type; isinstance(type, type) == True. Bởi vì chu kỳ kỳ lạ, dường như không thể, type này có thể được sử dụng để tạo ra các lớp học mới của lớp, (gọi là metaclasses). Bạn có thể viết:

class MyTypeSubclass(type): 
    pass 

class MyClass(object): 
    __metaclass__ = MyTypeSubclass 

hoặc, bằng Python 3:

class MyClass(metaclass=MyTypeSubclass): 
    pass 

nào cho kết quả thú vị mà isinstance(MyClass, MyTypeSubclass) == True. Tuy nhiên, điều này hữu ích hơn một chút so với phạm vi của câu trả lời này.

5

Đó là một cuộc gọi, cũng như các lớp học nói chung. Gọi dict() là hiệu quả để gọi hàm tạo dict. Điều này giống như khi bạn xác định lớp học của riêng bạn (C, nói) và bạn gọi số C() để khởi tạo nó.

+2

Tôi hiểu nó có thể gọi được, nhưng tại sao chúng ta gọi chúng là 'hàm' trên trang tài liệu? Có vẻ như có tên 'class' và' function' khá tầm thường. –

+1

@PhillipCloud Tôi hiểu sự khác biệt, nhưng chắc chắn bạn có thể thừa nhận rằng nó có một chút sai lầm khi có trang tài liệu nói hàm dựng sẵn khi người dùng định nghĩa các hàm có 'func_closure ',' func_code ',' func_defaults ',' func_dict ',' func_doc ' , 'func_globals', 'func_name'' và không có nội trang nào làm. –

+0

@EdgarAroutiounian Hàm khởi tạo thực sự là một phương thức trên đối tượng 'type'. Phương pháp này tất nhiên là một loại chức năng đặc biệt. Nó chắc chắn * không * tầm thường để tạo ra sự khác biệt giữa một hàm (không phải phương thức) được tạo ra bởi một câu lệnh 'def' và một lớp và hàm tạo của nó. Thực tế là bạn nghĩ rằng sự khác biệt này là tầm thường ngụ ý rằng bạn có thể đã không viết nhiều chức năng và/hoặc lớp học. Tôi cũng không nghĩ rằng việc gọi 'dict' là một hàm khó hiểu nếu bạn hiểu sự khác biệt giữa các lớp và các hàm và cách các lớp có liên quan đến các cuộc gọi. –

1

dict() là hàm tạo cho phiên bản dict. Khi bạn làm dir(dict), bạn đang xem các thuộc tính của lớp dict. Khi bạn viết a = dict(), bạn đang đặt a thành một loại mới dict.

Tôi giả định ở đây rằng dict() là những gì bạn đang gọi là "chức năng dict". Hoặc bạn đang gọi một phiên bản được lập chỉ mục là dict, ví dụ: a['my_key'] một chức năng?

+0

có, đề cập đến hàm 'dict()'. –

+0

Tôi nghĩ tốt hơn nên gọi nó là hàm tạo 'dict()', vì nó không chỉ là hàm khởi tạo. Nó cũng phân bổ một thể hiện mới. –

+0

@Codie CodeMonkey Tôi tự hỏi nếu mong muốn của bạn gọi '' dict() '' một nhà xây dựng không bị ảnh hưởng bởi các ngôn ngữ khác mà bạn chắc chắn biết. Tôi không đồng ý với mong muốn này. Thấy trong chỉ mục của doc, mục '' constructor'' dẫn đến '' object .__ init __ (self [, ...]) ''. Mọi thứ đủ phức tạp mà không cần thêm độ phức tạp bằng cách tự định nghĩa các từ đã có. – eyquem

0

Lưu ý rằng gọi dir trên constructor dict.__init__

dir(dict.__init__) 

mang đến cho bạn những gì bạn mong đợi, bao gồm cả những thứ giống như bạn muốn được đối với bất kỳ chức năng khác. Vì cuộc gọi đến hàm tạo dict() dẫn đến một cuộc gọi đến dict.__init__(instance), điều này giải thích nơi các thuộc tính chức năng đó đi đến. (Tất nhiên có thêm một chút công việc đằng sau hậu trường trong bất kỳ nhà xây dựng nào, nhưng cũng giống như đối với bất kỳ đối tượng nào.)

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