延迟评估函数参数

时间:2017-10-19 11:12:38

标签: python python-3.x

我正在尝试使用以下属性定义函数my_del

  • 它只有一个参数,
  • 如果传递的参数是具有全局赋值的变量,则使用del
  • 删除它
  • 否则打印“未分配变量”,
  • 不应发出NameError异常。

我的第一次试用:

def my_del(var):
    try: 
       del var
    except NameError:
       print("Variable not assigned")

这不起作用。

(i)对于指定的变量:

x = 1
my_del(x)
x
# outputs 1

该引用未被删除。虽然不确定,但我认为这是因为var没有绑定到全局x

(ii)对于未分配的变量,会发出异常:

my_del(y)
# NameError exception

函数my_del没有机会被调用,因为异常发生在之前。

我的第二次试验:

def my_del(var):
   try: 
       var = var()
       del var
   except NameError:
       print("Variable not assigned")

(i)对于未分配的变量:

my_del(lambda: y)
# prints the string

这很好用。

(ii)对于指定的变量:

x = 1
my_del(lambda: x)
x
# outputs 1

我们仍然引用了x。这里var = var()创建一个局部变量,它不引用输入参数。

创建此my_del函数的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

您还没有完全理解del的作用。 del只是将引用计数器递减到一个对象。在指向它的引用数为0(此时它是垃圾回收)之前,不会真正删除对象。在函数调用时,有(至少)两个引用 - 函数参数和传递给它的原始变量。此外,删除一个引用(var)并不意味着删除另一个引用(x)。

要查看当前指向对象的引用数,可以使用:

>>> import sys
>>> sys.getrefcount(x)

此外,如果my_del的唯一目的是(尝试)删除对象,请直接致电del ...

答案 1 :(得分:0)

你无法做到你想要做的事情,但是你可以通过直接操纵globals()字典来接近。但是,修改globals()通常是一个好主意。正如其他人所说,这样的功能没有实际用途。但无论如何......

我们无法直接传递我们想要删除的对象,但我们可以传递其名称。

def my_del(name):
    g = globals()
    if name in g:
        del g[name]
    else:
        print(name, 'unknown')

a = 7
print(a)
my_del('a')
try:
    print(a)
except NameError as e:
    print(e)

<强>输出

7
name 'a' is not defined