Python 函数参数的延迟求值

Python 函数参数的延迟求值,python,python-3.x,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 # outpu

我正在尝试使用以下属性定义函数
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
my_del(lambda: y)
# prints the string
x = 1
my_del(lambda: 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) 对于未赋值变量:

x = 1
my_del(x)
x
# outputs 1
my_del(lambda: y)
# prints the string
x = 1
my_del(lambda: x)
x
# outputs 1
这个很好用

(ii)对于指定变量:

x = 1
my_del(x)
x
# outputs 1
my_del(lambda: y)
# prints the string
x = 1
my_del(lambda: x)
x
# outputs 1
我们仍然引用了
x
。这里
var=var()
创建一个局部变量,它不引用输入参数



创建此
my\u del
函数的正确方法是什么?

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

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

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

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

您无法准确地完成您想要做的事情,但是您可以通过直接操作
globals()
dict来接近。但是,修改
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

这个函数没有任何意义。在函数内部,参数是一个参数;它是局部绑定的。在删除函数参数之前,函数参数上不能有
namererror
。正如您所看到的,当您试图解析缺少的标识符以将其值传递给函数时,
namererror
发生在函数外部。你能解释一下为什么你认为这是你想要的东西吗?@jornsharpe Re:“参数是一个参数;它是局部绑定的”。例如,在
def foo(var)var.append(5)
中,当定义一个列表
l
然后调用
foo(l)
时,我们可以说
var
是全局绑定的吗?关于:“背景”。我不会具体使用这个函数。我想看看这个想法是否可以实现(为了好玩和学习语言)。不,我们不能这么说,你只是在传递一个对可变对象的引用。如果没有上下文,这对其他人来说不是一个实用且可回答的问题。@jonrsharpe感谢您提供了关于可变对象的更多信息;dr-代码将引用计数递减1,如果没有使用引用调用函数,则不会递增:)(这是一个相当好的不执行任何操作的函数)@COLDSPEED感谢
sys.getrefcount
my_del
的思想基本上是一种
del
,如果变量未赋值,则不会发出NameError异常。这并不是关于它有多有用,而是关于如何实现它。@unfolx假设您在代码设计方面有点狡猾,这些东西可能不需要。。。无论如何,我希望这能让你朝着正确的方向迈出一步。@JonClements,在函数结束时,它会被递减!谢谢你回答这个问题。非常有用。很高兴了解
globals()
@unfolx无需担心。但是请不要像在普通代码中那样直接修改
globals()
。在开发过程中可以方便地检查
globals()
的内容,但您确实不应该更改它。@unfolx还有一个
locals()
dict,它等于模块的全局上下文中的
globals(),但在函数内部,它保存函数的局部变量。但是,对
locals()
的修改可能不会实际更改这些局部变量。请参阅“确定”,了解警告。感谢
本地人
和链接。