Python 有类似 Java 的匿名内部类的东西吗?
在 Java 中,您可以使用匿名内部类内联定义一个新类。 当您只需要重写类的单个方法时,这非常有用。
假设您要创建仅重写单个方法(例如 exit()
)的 OptionParser
子类。 在 Java 中,您可以编写如下内容:
new OptionParser () {
public void exit() {
// body of the method
}
};
这段代码创建一个扩展 OptionParser 的匿名类,并仅覆盖 exit()
方法。
Python中有类似的习惯用法吗? 在这些情况下使用哪种习语?
In Java you can define a new class inline using anonymous inner classes. This is useful when you need to rewrite only a single method of the class.
Suppose that you want create a subclass of OptionParser
that overrides only a single method (for example exit()
). In Java you can write something like this:
new OptionParser () {
public void exit() {
// body of the method
}
};
This piece of code creates a anonymous class that extends OptionParser
and override only the exit()
method.
There is a similar idiom in Python? Which idiom is used in these circumstances?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
您可以使用
type(name, bases, dict)
用于动态创建类的内置函数。 例如:由于 OptionParser 不是新式类,因此您必须在基类列表中显式包含
object
。You can use the
type(name, bases, dict)
builtin function to create classes on the fly. For example:Since OptionParser isn't a new-style class, you have to explicitly include
object
in the list of base classes.您可以通过三种方式完成此操作:
选项 3 的示例(经过编辑以删除“新”模块的使用——它已被弃用,我不知道):
You can accomplish this in three ways:
Example of option 3 (edited to remove use of "new" module -- It's deprecated, I did not know ):
Java 使用匿名类主要是为了模仿闭包或简单的代码块。 由于在 Python 中您可以轻松地传递方法,因此不需要像匿名内部类那样笨重的构造:
编辑:我知道这不是这种特殊情况下所需要的。 我刚刚描述了 Java 中匿名内部类最常见的问题的最常见的 Python 解决方案。
Java uses anonymous classes mostly to imitate closures or simply code blocks. Since in Python you can easily pass around methods there's no need for a construct as clunky as anonymous inner classes:
Edit: I'm aware that this is not what is needed in this special case. I just described the most common python solution to the problem most commonly by anonymous inner classes in Java.
好吧,类是第一类对象,因此如果需要,您可以在方法中创建它们。 例如
,但是,实际上,为什么不直接在正常级别定义类呢? 如果您需要自定义它,请将自定义内容作为参数放入
__init__
中。(编辑:修复了代码中的键入错误)
Well, classes are first class objects, so you can create them in methods if you want. e.g.
But, really, why not just define the class at the normal level? If you need to customise it, put the customisation in as arguments to
__init__
.(edit: fixed typing errors in code)
Python 不直接支持这一点(匿名类),但由于其简洁的语法,这实际上并不是必需的:
唯一的缺点是您将 MyOptionParser 添加到您的命名空间中,但正如 John Fouhy 指出的那样,您可以将其隐藏在函数中,如果您将多次执行此操作。
Python doesn't support this directly (anonymous classes) but because of its terse syntax it isn't really necessary:
The only downside is you add MyOptionParser to your namespace, but as John Fouhy pointed out, you can hide that inside a function if you are going to do it multiple times.
Python 可能有更好的方法来解决您的问题。 如果您可以提供有关您想要做什么的更具体的细节,将会有所帮助。
例如,如果您需要更改代码中特定点调用的方法,您可以通过将函数作为参数传递来完成此操作(函数是 python 中的第一类对象,您可以将它们传递给函数等)。 您还可以创建匿名 lambda 函数(但它们仅限于单个表达式)。
另外,由于 python 非常动态,因此您可以在创建对象后更改对象的方法
object.method1 = Alternative_impl1
,尽管它实际上有点复杂,请参阅 gnud 的答案Python probably has better ways to solve your problem. If you could provide more specific details of what you want to do it would help.
For example, if you need to change the method being called in a specific point in code, you can do this by passing the function as a parameter (functions are first class objects in python, you can pass them to functions, etc). You can also create anonymous
lambda
functions (but they're restricted to a single expression).Also, since python is very dynamic, you can change methods of an object after it's been created
object.method1 = alternative_impl1
, although it's actually a bit more complicated, see gnud's answer在 python 中,您有使用 lambda 语句声明的匿名函数。 我不太喜欢它们——它们的可读性较差,而且功能有限。
然而,你所讨论的可能是用完全不同的方法在 python 中实现的:
In python you have anonymous functions, declared using lambda statement. I do not like them very much - they are not so readable, and have limited functionality.
However, what you are talking about may be implemented in python with a completely different approach:
您始终可以通过变量隐藏类:
而不是
You can always hide class by variables:
instead of
这就是你在 Python 3.7 中要做的事情
This is what you would do in Python 3.7
我在 python3 中通常使用内部类执行此操作,
因为我使用了双下划线,这将“重整”与内部类的想法混合在一起,从外部您仍然可以使用 SomeSerializer._SomeSerializer__Paginator 访问内部类,并且子类,但 SomeSerializer.__Paginator 将不起作用,如果您希望它更加“匿名”,这可能是也可能不是您的愿望。
不过,如果您不需要重整,我建议使用带有单个下划线的“私有”表示法。
就我而言,我需要的是一个快速子类来设置一些类属性,然后将其分配给我的 RestSerializer 类的类属性,因此双下划线表示“根本不再使用它”并且可能会更改为没有下划线,如果我开始在其他地方重用它。
I do this in python3 usually with inner classes
as i used double underscore, this mixes the idea of "mangling" with inner classes, from outside you can still access the inner class with
SomeSerializer._SomeSerializer__Paginator
, and also subclasses, but SomeSerializer.__Paginator will not work, which might or might not be your whish if you want it a bit more "anonymous".However I suggest to use "private" notation with a single underscore, if you do not need the mangling.
In my case, all I need is a fast subclass to set some class attributes, followed up by assigning it to the class attribute of my RestSerializer class, so the double underscore would denote to "not use it at all further" and might change to no underscores, if I start reusing it elsewhere.
反常的是,您可以使用一次性名称
_
作为派生类名称:Being perverse, you could use the throwaway name
_
for the derived class name:这是执行 Maciej 的方法的更奇特的方式。
我定义了以下装饰器:
以下代码大致相同(也适用于参数!)
如果您想定义“内部”类实例,则可以在类/方法/函数中使用此代码。
Here is a more fancy way of doing Maciej's method.
I defined the following decorator:
The following codes are roughly equivalent (also works with args!)
You can use this code from within a class/method/function if you want to define an "inner" class instance.