Có cách nào để xóa các biến, hàm, v.v. đã tạo khỏi bộ nhớ của trình thông dịch không?


113

Tôi đã tìm kiếm câu trả lời chính xác cho câu hỏi này trong vài ngày nay nhưng không có gì tốt. Tôi không phải là một người mới bắt đầu hoàn toàn trong lập trình, nhưng thậm chí chưa ở trình độ trung cấp.

Khi tôi ở trong shell của Python, tôi nhập: dir()và tôi có thể thấy tất cả tên của tất cả các đối tượng trong phạm vi hiện tại (khối chính), có 6 trong số chúng:

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

Sau đó, khi tôi khai báo một biến, chẳng hạn x = 10, nó sẽ tự động thêm vào danh sách các đối tượng trong mô-đun tích hợp sẵn dir()và khi tôi nhập dir()lại, nó hiển thị ngay bây giờ:

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x']

Điều này cũng xảy ra với các hàm, lớp, v.v.

Làm cách nào để xóa tất cả các đối tượng mới đó mà không xóa tiêu chuẩn 6 có sẵn ở đầu?

Tôi đã đọc ở đây về "dọn dẹp bộ nhớ", "làm sạch bảng điều khiển", xóa tất cả văn bản khỏi cửa sổ nhắc lệnh:

>>> import sys
>>> clear = lambda: os.system('cls')
>>> clear()

Nhưng tất cả những điều này không liên quan gì đến những gì tôi đang cố gắng đạt được, nó không làm sạch tất cả các đồ vật đã sử dụng.


2
Tại sao bạn cảm thấy mình cần phải làm điều này, hay bạn chỉ hỏi vì tò mò?
PM 2Ring

Tôi chỉ không biết rằng có một delchức năng ở đó. Tôi đang bắt đầu học Python và thường phải thử nghiệm trong shell, vì vậy các tên biến tiêu chuẩn như xhoặc ythường đã được sử dụng và việc khởi động lại shell sẽ mất thêm 15 giây để thực hiện (hiện tại tôi có một máy tính xách tay rất cũ). Vì vậy, tôi muốn tìm cách làm sạch bộ nhớ Python nhanh hơn.
Mushhorn

1
Ah. FWIW, delkhông hẳn là một hàm, do đó không (). Đó là một từ khóa giới thiệu một câu lệnh del. Tất nhiên, làm thế nào nó thực sự xóa một đối tượng có thể bao gồm các chức năng, nhưng đó là một câu chuyện ...
PM 2Ring

Khi thử nghiệm các tên shell như xhoặc ykhông nên được sử dụng trừ khi bạn đang sử dụng chúng. Hoặc trừ khi bạn làm điều gì đó ngớ ngẩn như vậy from _somemodule_ import *, thì bạn sẽ nhận được đủ loại rác bừa bãi ở nơi đó. :)
PM 2Ring

1
Tôi đã truy cập vào câu hỏi này và bây giờ tôi đang tự hỏi - tại sao tôi không thể khởi động lại hạt nhân và chạy lại tập lệnh từ đầu nếu tôi vẫn muốn xóa tất cả các biến và hàm?
vagabond

Câu trả lời:


159

Bạn có thể xóa các tên riêng lẻ bằng del:

del x

hoặc bạn có thể xóa chúng khỏi globals()đối tượng:

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

Đây chỉ là một vòng lặp ví dụ; nó chỉ xóa một cách phòng thủ những tên không bắt đầu bằng dấu gạch dưới, tạo ra giả định (không phải là không có lý do) rằng bạn chỉ sử dụng những tên không có dấu gạch dưới ở đầu trong trình thông dịch của bạn. Bạn có thể sử dụng danh sách các tên được mã hóa cứng để giữ lại thay thế (danh sách trắng) nếu bạn thực sự muốn tìm hiểu kỹ lưỡng. Không có chức năng tích hợp nào để thực hiện việc xóa cho bạn, ngoài việc chỉ thoát và khởi động lại trình thông dịch.

Các mô-đun bạn đã nhập ( import os) sẽ vẫn được nhập vì chúng được tham chiếu bởi sys.modules; các lần nhập tiếp theo sẽ sử dụng lại đối tượng mô-đun đã được nhập. Bạn sẽ không có tham chiếu đến chúng trong không gian tên chung hiện tại của mình.


Vâng, tôi phải nói là startswith('_')có vẻ khá ngây thơ. Nếu ai đó đủ thông minh để viết _foo=42hoặc thậm chí __foo__=42, làm thế nào chúng ta có thể xóa chúng? Có cách nào để lấy tên thuộc tính mô-đun tiêu chuẩn theo chương trình không?
georg

2
@georg: Tôi đã mã hóa vòng lặp phòng thủ. Bạn sẽ phải mã hóa một danh sách ban đầu các tên để giữ lại nếu bạn muốn làm tốt hơn.
Martijn Pieters

Vì vậy, không có cách nào? Ý nghĩ của tôi là dir(ModuleType()), nhưng nó chỉ trở lại docname.
georg

1
@georg: không; không gian tên chung của trình thông dịch cũng thay đổi theo từng phiên bản và không có cách nào dễ hiểu (mà tôi biết) để liệt kê những gì đã có trong đó khi bạn mở trình thông dịch ở giai đoạn sau .
Martijn Pieters

1
Các hàm và lớp @nakE chỉ là các đối tượng giống như bất kỳ đối tượng nào khác. Chúng không đặc biệt; sử dụng danh sách trắng hoặc kiểm tra loại đối tượng mà bạn cần để bảo toàn các lớp và hàm.
Martijn Pieters

67

Đúng. Có một cách đơn giản để xóa mọi thứ trong iPython. Trong bảng điều khiển iPython, chỉ cần nhập:

%reset

Sau đó hệ thống sẽ yêu cầu bạn xác nhận. Nhấn phím y. Nếu bạn không muốn thấy lời nhắc này, chỉ cần nhập:

%reset -f

Điều này sẽ hoạt động ..


1
Một lần nữa, tại sao đây không phải là câu trả lời hàng đầu?
myradio

11
@myradio Bởi vì nó không liên quan đến việc mọi người không sử dụng IPython , và nó không trả lời câu hỏi; câu hỏi hỏi cách xóa các tham chiếu đối tượng toàn cục, không đặt lại nội dung của trình bao IPython .
Andreas

17

Bạn có thể sử dụng trình thu gom rác python:

import gc
gc.collect()

6
Này @Fardin! cảm ơn! Câu trả lời của bạn đã thực hiện công việc và tiết kiệm ngày của tôi! Nhưng trước gc.collect () tôi đã làm del (biến).
Gmosy Gnaq,

9

Nếu bạn đang ở trong một môi trường tương tác như Jupyterhoặc ipythonbạn có thể quan tâm đến việc xóa các var không mong muốn nếu chúng ngày càng nặng.

Các lệnh ma thuật resetreset_selectivecó sẵn trên các phiên python tương tác như ipythonJupyter

1) reset

reset Đặt lại không gian tên bằng cách xóa tất cả các tên do người dùng xác định, nếu được gọi mà không có đối số.

invà các outtham số chỉ định xem bạn có muốn xóa bộ đệm vào / ra hay không. Lịch sử thư mục được xóa bằng dhisttham số.

reset in out

Một điều thú vị khác là arraychỉ loại bỏ Mảng không có hạt:

reset array

2) reset_selective

Đặt lại không gian tên bằng cách xóa tên do người dùng xác định. Lịch sử đầu vào / đầu ra được để lại trong trường hợp bạn cần chúng.

Ví dụ về mảng sạch:

In [1]: import numpy as np
In [2]: littleArray = np.array([1,2,3,4,5])
In [3]: who_ls
Out[3]: ['littleArray', 'np']
In [4]: reset_selective -f littleArray
In [5]: who_ls
Out[5]: ['np']

Nguồn: http://ipython.readthedocs.io/en/stable/interactive/magics.html


6

Điều này đã làm việc cho tôi.

Bạn cần chạy nó hai lần một lần cho những quả cầu được người dân địa phương theo dõi

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

for name in dir():
    if not name.startswith('_'):
        del locals()[name]

4

Trên thực tế, python sẽ lấy lại bộ nhớ không được sử dụng nữa, đây được gọi là thu thập rác , là quá trình tự động trong python. Nhưng nếu bạn muốn làm điều đó thì bạn có thể xóa nó đi del variable_name. Bạn cũng có thể làm điều đó bằng cách gán biến choNone

a = 10
print a 

del a       
print a      ## throws an error here because it's been deleted already.

Cách duy nhất để thực sự lấy lại bộ nhớ từ các đối tượng Python không được tham chiếu là thông qua trình thu gom rác. Từ khóa del chỉ đơn giản là hủy liên kết tên khỏi một đối tượng, nhưng đối tượng vẫn cần được thu gom. Bạn có thể buộc trình thu gom rác chạy bằng mô-đun gc, nhưng đây gần như chắc chắn là một sự tối ưu hóa quá sớm nhưng nó có những rủi ro riêng. Việc sử dụng delkhông có tác dụng thực sự, vì dù sao thì những cái tên đó cũng đã bị xóa khi chúng vượt ra khỏi phạm vi.


Thật. Tất nhiên, khi làm việc trong không gian tên chung của trình thông dịch, tên không gian tên chung của trình thông dịch sẽ không vượt ra ngoài phạm vi, nhưng vậy thì sao. :) Tôi đoán cũng cần nhắc lại rằng những gì xảy ra với bộ nhớ được sử dụng bởi các đối tượng đã được thu thập rác là phụ thuộc vào việc triển khai, nhưng trong hầu hết các triển khai Python, bộ nhớ gc'ed chỉ quay trở lại nhóm Python, nó không được trả về Hệ điều hành cho đến khi chương trình thoát.
PM 2Ring

@ PM2Ring LOL :) Tôi nghĩ vậy. Bạn tham khảo python từ đâu?
d-coder

2
Lưu ý rằng trong CPython, GC chỉ cần thiết để phá vỡ các chu kỳ tham chiếu. Nếu không còn tham chiếu nào, một đối tượng sẽ bị xóa khỏi bộ nhớ. Vì vậy, del không có một tác động thực sự ở đây.
Martijn Pieters

@MartijnPieters, đã xóa insta? Đó có phải là một thuật ngữ kỹ thuật không? :)
Eryk Sun

2
@eryksun: vâng, tất nhiên như được định nghĩa bởi RFC 4042-bis2! :-P
Martijn Pieters
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.