2

I am new in Python. There is a function in R called ls(). I can easily remove any created objects using ls() and rm() functions as bellow.

R Code

# Create x and y
x = 1
y = "a"

# remove all created objects
ls()
# [1] "x" "y"
rm(list = ls())

# Try to print x
x
# Error: object 'x' not found 

In this post someone suggested an equivalent of ls() in python. So, I have tried to do the same operation in python.

Python Code

# Create x and y
x = 1
y = "a"

# remove all created objects
for v in dir(): del globals()[v]

# Try to print x
x
# NameError: name 'x' is not defined

But the problem is when x is recreated and printed it is throwing error:

# Recreate x
x = 1

# Try to print x
x

Traceback (most recent call last):

File "", line 1, in x

File "C:\SomePath\Anaconda\lib\site-packages\IPython\core\displayhook.py", line 258, in call self.update_user_ns(result)

File "C:\SomePath\Anaconda\lib\site-packages\IPython\core\displayhook.py", line 196, in update_user_ns if result is not self.shell.user_ns['_oh']:

KeyError: '_oh'

I have noticed dir() give some extra objects other than my objects. Is there any function which will give the same output like R's ls()?

taras
  • 6,566
  • 10
  • 39
  • 50
Raja
  • 157
  • 1
  • 11
  • why not just `del x`? you don't need to delete everything in `globals()`, this is asking for trouble! (BTW can't reproduce in the python interactive mode, guess this is something related to your setup) – Chris_Rands Aug 23 '18 at 09:17
  • If this is about IPython specifically, you can always restart your kernel with `Ctrl+.` to be in a fresh new environment. – Jeronimo Aug 23 '18 at 09:17
  • or perhaps. `for v in dir(): if not v.startswith('_'): del globals()[v]` to keep private stuff – Chris_Rands Aug 23 '18 at 09:18
  • What if I have too many objects to delete? @Chris_Rands – Raja Aug 23 '18 at 09:19
  • 2
    See my 2nd comment, but this is a pretty odd thing to want to do, why do you need to clear the namespace like this? – Chris_Rands Aug 23 '18 at 09:19
  • I might have a object like __MyObject__ (Start with underscore, not showing in the comment). Then? @Chris_Rands – Raja Aug 23 '18 at 09:22
  • The below SO link has the answer.. Please have a look. It seems similar. https://stackoverflow.com/questions/33549854/equivalent-of-r-ls-but-only-for-user-generated-objects-functions – Arihant Aug 23 '18 at 09:29
  • Thanks @Arihant That was the closest solution of my problem. – Raja Aug 23 '18 at 10:02
  • 1
    What do you want to achieve? Why can't you just start a new interpreter? – mkrieger1 Aug 23 '18 at 10:11

3 Answers3

4

There are different questions here.

Is this code correct?

# remove all created objects
for v in dir(): del globals()[v]

No it is not! First dir() returns the keys from the local mapping. At module level, it is the same as globals(), but not inside a function. Next it contains some objects that you do not want to remove like __builtins__...

Is there any function which will give the same output like R's ls()?

Not exactly, but you can try to mimic it with a class:

class Cleaner:
    def __init__(self):
        self.reset()
    def reset(self):
        self.keep = set(globals());
    def clean(self):
        g = list(globals())
        for __i in g:
            if __i not in self.keep:
                # print("Removing", __i)      # uncomment for tracing what happens
                del globals()[__i]

When you create a cleaner object, it keeps a list (more exactly a set object) of all pre-existing objects. When you call its clean method, it removes from its globals() mapping all objects that were added since its creation (including itself!)

Example (with uncommented tracing):

>>> class Cleaner:
    def __init__(self):
        self.reset()
    def reset(self):
        self.keep = set(globals());
    def clean(self):
        g = list(globals())
        for __i in g:
            if __i not in self.keep:
                print("Removing", __i)      # uncomment for tracing what happens
                del globals()[__i]


>>> dir()
['Cleaner', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> c = Cleaner()
>>> i = 1 + 2
>>> import sys
>>> dir()
['Cleaner', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'c', 'i', 'sys']
>>> c.clean()
Removing c
Removing i
Removing sys
>>> dir()
['Cleaner', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
2

Base on @Arihant's comment I have tried:

zzz = %who_ls
for v in zzz : del globals()[v]
del v,zzz

I hope this could be done in a single line. Any suggestions are welcome.

Another similar solution is:

%reset -f
Raja
  • 157
  • 1
  • 11
2

Coming from R, the most satisfactory solution I've found is to simply restart the kernel. The downside is that you lose all your imports, but I've learned to live with that.

  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/low-quality-posts/27069549) – zabop Sep 01 '20 at 22:09
  • 3
    Okay: "just restart the kernel". That answers the question. – Charles Becker Sep 02 '20 at 23:17