2015-08-06 16 views
5

Tôi phát hiện ra điều này một cách ngẫu nhiên ngày hôm nay khi tôi nhận thấy một đoạn mã Python đã sử dụng built-in functionall làm mã định danh biến để lưu trữ kết quả của việc hiểu danh sách và nó không gây ra lỗi, vì vậy tôi đã thử như sau :Tại sao bạn có thể gán giá trị cho các hàm dựng sẵn trong Python?

type('abc') 
Out[1]: str 

type('abc') == str 
Out[2]: True 

str = int 

type('abc') == str 
Out[4]: False 

type('abc') 
Out[5]: str 

type = [1,2,3] 

type('abc') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-7-a74a7df76db1> in <module>() 
----> 1 type('abc') 

TypeError: 'list' object is not callable 

Hy vọng rằng, đó là câu hỏi hợp lệ khi tôi hỏi lý do hành vi này được cho phép bằng Python.

Hoặc tốt hơn, làm thế nào để đảm bảo rằng một built-in chức năng như str thực sự str và không nói, int nên str(123) sẽ không được đánh giá là int(123) một cách tình cờ?

+3

Bạn không thực sự phân công lại bất kỳ built-in đối tượng. Bạn đã định nghĩa các hình cầu mới che dấu các phần tích hợp sẵn. Tại sao? Bởi vì Python là linh hoạt như thế. –

+0

Tại sao Python nên ngăn bạn đặt tên bất cứ thứ gì bạn muốn? Đó là trách nhiệm của bạn để lại tên của những người xây dựng quan trọng một mình nếu bạn muốn họ hành động bình thường. –

+0

@MartijnPieters Điều đó thực sự khá thú vị nhưng làm thế nào để đảm bảo rằng một chức năng làm những gì tôi nghĩ rằng nó sẽ làm gì? – Vinayak

Trả lời

6

Python hy vọng bạn chịu trách nhiệm về mã của mình, là lý do. Python không có thuộc tính riêng tư, không có lớp được bảo vệ và hầu như không có giới hạn về tên bạn có thể sử dụng.

Có, điều đó có nghĩa là bạn vô tình đổi tên được tích hợp sẵn. Tạo unittests cho mã của bạn, sử dụng một linter, và nói chung, bạn sẽ nhanh chóng tìm hiểu để phát hiện tình cờ sử dụng một built-in bạn cần. Không khác gì việc vô tình sử dụng lại bất kỳ tên nào khác trong mã của bạn.

Lưu ý rằng bạn chỉ cần đeo mặt nạ tên được cài sẵn; tra cứu tên mà không tìm thấy một cái nhìn toàn cầu tiếp theo tại không gian tên được xây dựng trong, vì vậy nếu bạn đặt str cho cái gì khác, được tìm thấy trước khi được xây dựng trong. Bạn chỉ cần xóa toàn cầu:

>>> str = 'foobar' 
>>> isinstance('foobar', str) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types 
>>> del str 
>>> isinstance('foobar', str) 
True 

Việc thay thế sẽ được để làm cho mọi built-in tên một từ khóa dành riêng, để lại cho bạn một danh sách nhiều giảm bớt các tên mà được cho phép, và không có sự linh hoạt trong việc tái xác định các đối tượng. Ví dụ, Python 2.7 có 144 tên như vậy.

Trong bối cảnh này, hãy xem blog post by Guido van Rossum on why None, True and False are now keywords in Python 3:

Because you cannot use these as variable or function names anywhere, ever, in any Python program, everyone using Python has to know about all the reserved words in the language, even if they don't have any need for them. For this reason, we try to keep the list of reserved words small, and the core developers hem and haw a lot before adding a new reserved word to the language.

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