简体   繁体   English

python中的空函数对象

[英]empty function object in python

I've heard that python functions are objects, similar to lists or dictionaries, etc. However, what would be a similar way of performing this type of action with a function? 我听说python函数是对象,类似于列表或字典等。但是,使用函数执行此类操作的类似方法是什么?

# Assigning empty list to 'a'
a = list()

# Assigning empty function to 'a'
a = lambda: pass
# ???

How would you do this? 你会怎么做? Further, is it necessary or proper? 此外,是否必要或适当? Here is the sense in which I would like to use it for better context: 以下是我想将其用于更好的上下文的意义:

I have a QListWidget for selecting items which are associated with keys in a dictionary. 我有一个QListWidget用于选择与字典中的键相关联的项目。 The values in this dictionary are also dictionaries, which hold certain properties of the items, which I can add. 此字典中的值也是字典,它包含项目的某些属性,我可以添加。 These certain properties are stored as keys, and the values in them are initialized or updated by calling different functions. 这些特定属性存储为键,并通过调用不同的函数初始化或更新它们中的值。 So, I'm storing a variable in the window which gets updated when a button is pressed to tell this script which property to update. 所以,我在窗口中存储一个变量,当按下一个按钮告诉该脚本要更新哪个属性时,该变量会更新。

As you can see, I would like to store the function to map to the data using the correct function based on the situation. 如您所见,我想根据情况使用正确的函数存储函数以映射到数据。

# Get selection from the list
name = selected_item
# Initialize an empty function
f = lambda: pass
# Use property that is being added now, which was updated by the specific button that was pushed
property_list = items[name][self.property_currently_being_added]
if self.property_currently_being_added == "prop1":
    f = make_property1()
elif self.property_currently_being_added == "prop2":
    f = make_property2()
elif self.property_currently_being_added == "prop3":
    f = make_property3()
elif self.property_currently_being_added == "prop4":
    f = make_property4()

# map the certain function to the data which was retrieved earlier
added_property = map(f, data)
property_list.append(added_property)

First, the reason this doesn't work: 首先,这不起作用的原因:

a = lamdba: pass

… is that lambda only allows an expression, and defines a function that returns the value of the expression. ...是lambda只允许表达式,并定义一个返回表达式值的函数。 Since pass is a statement, not an expression, this is illegal. 由于pass是声明而不是表达式,因此这是非法的。

However, this works just fine: 但是,这很好用:

a = lambda: None

In Python, a function that falls off the end without a return statement always returns None . 在Python中,一个没有return语句的函数总是返回None So, these are equivalent: 所以,这些是等价的:

def a(): return None
def a(): pass

However, I don't see why you want to write this as a lambda and an assignment anyway; 但是,我不明白你为什么要把它写成一个lambda和一个任务; the def is shorter, and more readable, and gives you an introspectable function object with a nice name ( a instead of <lambda> ), and so on. def较短,更易读的,并给出了你一个好听的名字的内省功能对象( a ,而不是<lambda> ),等等。 The only reasons to ever use lambda are when you don't want to give the function a name, or when you need to define the function inside an expression. 使用lambda的唯一原因是当你不想给函数命名时,或者你需要在表达式中定义函数时。 Obviously neither of those are true, because you use the lambda directly inside an assignment statement. 显然这两者都不正确,因为你直接在赋值语句中使用lambda So, just use def . 所以,只需使用def


Meanwhile, this is in a sense an "empty function", or at least as empty as possible (as you can see by, eg, calling dis.dis(a) , it still takes two bytecodes to do nothing but fall off the end and return None ), but it's not useful for your case. 同时,这在某种意义上是一个“空函数”,或者至少尽可能为空(正如你可以看到的那样,例如,调用dis.dis(a) ,它仍然需要两个字节代码才能做什么,但是从最后掉下来并返回None ),但它对你的情况没用。 You don't want an "empty function". 你不想要一个“空函数”。 If you try passing your a to map , you're just going to get a TypeError , because you're trying to call a function of no arguments with one argument. 如果你尝试将a传递给map ,那么你只会得到一个TypeError ,因为你试图用一个参数调用一个没有参数的函数。 (Because that's what map does.) (因为这就是map所做的。)

What you might want is an identity function, which just returns its argument as-is. 你可能想要的是一个身份函数,它只是按原样返回它的参数。 Like this: 像这样:

def a(x): return x

But I'm not sure that's what you want. 但我不确定那是你想要的。 Did you want to append data as-is in that case? 在这种情况下,您是否要按原样附加data Or did you want to do something different, like return early, or raise an exception, or not append anything, or …? 或者你想做一些不同的事情,比如早退,或提出异常,或不附加任何东西,或......?


Finally, I don't see why you want a function at all. 最后,我不明白为什么你想要一个功能。 Why not just not call map if you have nothing to map? 为什么不干脆不叫map ,如果你有什么地图? You have a perfectly good else clause that already catches that case (especially handy if what you want to do is return early or raise…). 你有一个非常好的else条款已经捕获了这种情况(如果你想做的事情是提前返回或提高......),这是非常方便的。 Or, if you prefer, you can start with f = None , and then use an if f: do decide whether to map or not. 或者,如果您愿意,可以从f = None开始,然后使用if f:确定是否映射。 Or, if you really want: 或者,如果你真的想要:

added_property = [f(element) if f else element for element in data]

… or … … 要么 …

added_property = map(f, data) if f else data

As one last note, instead of a long if / elif chain that repeats the same thing over and over again, you might want a dict : 作为最后一个注释,你可能想要一个dict ,而不是一遍又一遍地重复同一个东西的if / elif链。

propfuncs = {'prop1': make_property1(),
             'prop2': make_property2(),
             'prop3': make_property3(),
             'prop4': make_property4()}

Then, all that cruft turns into these two lines: 然后,所有这些残余变成了这两行:

f = propfuncs.get(self.property_currently_being_added)
added_property = map(f, data) if f else data

Or course an even better design might be to replace all those make_propertyN functions with a single function that you call as make_property(1) or make_property('prop1') … but without seeing what they actually do, I can't be sure of that. 或者更好的设计可能是将所有make_propertyN函数替换为您调用为make_property(1)make_property('prop1')的单个函数...但是没有看到它们实际执行的操作,我无法确定。

I am surprised to learn that you can even do... 我很惊讶你甚至可以做到......

def a(): "This is a test"

a()

这感觉非常像你正在寻找一个Nothing functor,我猜你如果你对Monads有所了解,你甚至不需要一个空函数,因为灵感PyMonad有一个很好的Nothing实现,我通常喜欢创建我自己的,但这是一个很好的起点。

For completeness and since the title is "empty function object in python", more general case is an empty function object that takes any number of parameters , so you can use it in any callback. 为了完整性,由于标题是“python中的空函数对象”,更一般的情况是一个空函数对象,它接受任意数量的参数 ,因此您可以在任何回调中使用它。 It's this one: 就是这个:

callback = lambda *_, **__: None

Explanation is here: http://echochamber.me/viewtopic.php?t=64825 解释如下: http//echochamber.me/viewtopic.php?t = 64825

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM