2013-05-13 44 views
15

Tôi đã thực hiện một sai lầm như sau:Đặt tên xung đột với built-in chức năng

>>> list = ['a', 'b', 'c'] 

Nhưng bây giờ tôi muốn sử dụng được xây dựng trong chức năng list(). Như bạn có thể thấy, có một xung đột đặt tên giữa tên danh sách list và hàm dựng sẵn list().

Làm cách nào để sử dụng list làm chức năng tích hợp chứ không phải biến mà không cần khởi động lại trình bao Python?

+2

câu hỏi hay, chúng ta nên liên kết đến điều này bất cứ khi nào mọi người sử dụng tên dựng sẵn – jamylak

+2

Lưu ý đáng giá: có thể sử dụng một trong các phương pháp bên dưới để truy cập phiên bản tích hợp và rebind tên 'list' với nó, để hoàn tác sai lầm của bạn. 'list = __builtins __. list' –

Trả lời

26

Sử dụng __builtins__.list hoặc __builtins__['__list__'] (tùy theo ngữ cảnh), hoặc chỉ cần xóa lại list (del list).

Không nhập khẩu cần thiết:

>>> __builtins__.list 
<type 'list'> 

Sự hiện diện của __builtins__ là một chi tiết thực hiện CPython; trong mô-đun __main__ nó là một mô-đun, ở mọi nơi khác nó là mô-đun __dict__ từ điển. Jython, IronPython và PyPy có thể chọn không làm cho tính năng này khả dụng. Sử dụng các __builtin__ module cho những nền tảng, hoặc cho Python 3 triển khai tương thích, builtins module:

>>> import __builtin__ 
>>> __builtin__.list 
<type 'list'> 
+6

Re: '__builtins __. List' - không làm điều này. Chỉ vì bạn không thể có nghĩa là bạn nên. – FogleBird

+1

@FogleBird Với tình huống mà OP đưa ra - một sai lầm tại thông dịch viên, tôi không nghĩ có bất cứ điều gì sai trái khi thực hiện việc này. Rõ ràng là trong bất kỳ mã nào được viết trong một tệp, đó là một trường hợp khác. –

+0

ipdb nhận được đối tượng "*** AttributeError: 'dict' không có thuộc tính 'list'", tôi sử dụng '__builtings __ ['list']' – Pegasus

2

sử dụng __builtin__.list trong py2x:

>>> import __builtin__ 
>>> __builtin__.list 
<type 'list'> 

Không sử dụng __builtins__.list:

Từ docs:

CPython implementation detail: Users should not touch __builtins__ ; it is strictly an implementation detail. Users wanting to override values in the builtins namespace should import the __builtin__ (no ‘s’) module and modify its attributes appropriately.

cho py3x:

>>> import builtins 
>>> builtins.list 
<class 'list'> 
+0

Không cần' import', AFAIK. –

+1

'__builtins__', không phải' __builtin__' –

+1

@HenryKeiter: Không, có một mô-đun ['__builtin__'] (http://docs.python.org/2/library/__builtin__.html). –

8

Không sử dụng built-in chức năng, hoặc các loại như tên biến. Nó chỉ đơn giản như vậy, ngôn ngữ không có nghĩa là cho điều đó. Và nó không có ý nghĩa để làm như vậy.

Không chỉ vậy - nhưng sử dụng tên "danh sách" cho một danh sách là rất mơ hồ, và tôi nghi ngờ nó thậm chí còn có thể sử dụng từ xa trong bất kỳ mã thực.


Có một vài lý do tại sao bạn nên KHÔNGbao giờ bóng một built-in. Một số trường hợp nghiêm trọng hơn là dưới đây:

  • Tính tương thích, mã sẽ không hoạt động với các mô-đun khác.
  • Lẫn lộn, bất kỳ ai đọc mã của bạn sẽ không hiểu điều gì đang diễn ra.
  • Trường hợp, nhiều người dùng tích hợp sử dụng các trình cài sẵn khác, việc thay đổi có thể có kết quả không mong muốn trên các khía cạnh khác của mã.
+6

Điều này không trả lời câu hỏi - OP hiểu rằng những gì ông đã làm là sai, nhưng ông đang sử dụng vỏ và muốn sửa lỗi. –

1

Nó phải lúc nào cũng có sẵn như là __builtins__.list:

>>> __builtins__.list 
<class 'list'> 
>>> list = [1, 2, 3] 
>>> __builtins__.list 
<class 'list'> 

Nếu bạn tình cờ rebind rằng, tuy nhiên, bạn không gặp các tùy chọn.

Bạn cũng có thể sử dụng mô-đun __builtin__ (hoặc builtins, không có dấu gạch dưới, trong Python 3) nhưng bạn phải nhập. Nhưng đây là những cách khác nhau để đánh vần các điều tương tự, chứ không phải là một tùy chọn thêm - sửa đổi một ảnh hưởng đến cả hai:

>>> import builtins 
>>> builtins.list 
<class 'list'> 
>>> builtins.list = [1, 2, 3] 
>>> builtins.list 
[1, 2, 3] 
>>> __builtins__.list 
[1, 2, 3] 
+0

Không sử dụng '__builtins__': http://docs.python.org/2/reference/executionmodel.html –

28

Bước một: rebind danh sách việc cần một cái tên khác

lst = list 

bước hai: xóa các list biến

del list 

Bước ba: không làm điều đó một lần nữa


Tôi thích này trên __builtins__.list đơn giản chỉ vì nó tiết kiệm các đánh máy, và bạn không còn trái với một biến có tên list. Tuy nhiên, cách tốt nhất là tránh vấn đề hoàn toàn. Khi viết mã sản xuất, luôn nhớ không phải để có các biến có tên giống như các hàm được tích hợp sẵn.

+1

Đây là một câu trả lời tuyệt vời. Ngoài những lợi thế bạn đã đề cập, nó không dựa vào chi tiết thực hiện CPython! – Adam

+0

Xin lỗi, đây là câu trả lời không tốt trong cuốn sách của tôi. -1. Nó chắc chắn là một khả năng, nhưng nó sẽ chống lại những gì tôi tin là sự nhạy cảm của mã hóa. Điều này làm cho mã của bạn bị tách rời khỏi các Python khác ở mọi nơi, Bất kỳ ai nhìn vào các đoạn mã sẽ trở nên bối rối, và nó sẽ không hoạt động tốt với các mô-đun khác. Nói cách khác, điều này sẽ BREAK liên tục và RẤT mong manh. –

+9

@InbarRose Câu hỏi đặc biệt áp dụng cho trình thông dịch Python. Sử dụng * bất kỳ * của các hacks được cung cấp trong các câu trả lời sẽ là * điên * trong mã sản xuất - và do đó, tôi có nghĩa là bất kỳ mã nào được viết bên ngoài trình thông dịch trực tiếp. – Adam

0

Có, những người khác đang nói ở trên, không sử dụng tên của nội trang dựng sẵn dưới dạng tên biến. Điều này xảy ra cho list, dict, v.v.

Tương tự như vậy, những người khác đã nói, bạn có quyền truy cập vào loại list đến __builtins__.list. Vì vậy, nếu bạn cần gọi số list, bạn vẫn có thể tìm thấy nó, miễn là bạn chưa hồi phục __builtins__.list cũng vậy.

Quan trọng, tuy nhiên, list là tên. Bạn đã khôi phục nó về một thể hiện của một danh sách. Nếu bạn muốn list có nghĩa là <type 'list'> một lần nữa, chỉ cần khởi động lại nó. Trong Python 2.7:

>>> __builtins__.list 
<type 'list'> 
>>> list 
<type 'list'> 
>>> list = [1, 2, 3] 
>>> list 
[1, 2, 3] 
>>> fred = list 
>>> fred 
[1, 2, 3] 
>>> list = __builtins__.list 
>>> list 
<type 'list'> 
4

Để sửa chữa sai lầm, có một tùy chọn - nếu chúng ta nhớ rằng các built-in 'chức năng' list() thực sự là một lớp, sau đó chúng tôi chỉ có thể làm điều này:

list = type([]) 
Các vấn đề liên quan