And*_*cia 39 python class anonymous-class
在Java中,您可以使用匿名内部类定义新的内联类.当您只需要重写该类的单个方法时,这非常有用.
假设您要创建一个子类OptionParser
,只覆盖一个方法(例如exit()
).在Java中,您可以编写如下内容:
new OptionParser () {
public void exit() {
// body of the method
}
};
Run Code Online (Sandbox Code Playgroud)
这段代码创建了一个匿名类,OptionParser
它只扩展和覆盖该exit()
方法.
Python中有类似的习惯用法吗?在这些情况下使用哪种成语?
Joe*_*and 38
您可以使用type(name, bases, dict)
内置函数动态创建类.例如:
op = type("MyOptionParser", (OptionParser,object), {"foo": lambda self: "foo" })
op().foo()
Run Code Online (Sandbox Code Playgroud)
由于OptionParser不是新式类,因此必须明确包含object
在基类列表中.
Joa*_*uer 18
Java主要使用匿名类来模仿闭包或简单地编写代码块.因为在Python中你可以很容易地传递方法,所以不需要像匿名内部类那样笨重的构造:
def printStuff():
print "hello"
def doit(what):
what()
doit(printStuff)
Run Code Online (Sandbox Code Playgroud)
编辑:我知道这不是这个特例所需要的.我刚刚描述了Java中匿名内部类最常见的python解决方案.
gnu*_*nud 12
您可以通过三种方式完成此任务:
选项3的示例(已编辑以删除"新"模块的使用 - 它已被弃用,我不知道):
import types
class someclass(object):
val = "Value"
def some_method(self):
print self.val
def some_method_upper(self):
print self.val.upper()
obj = someclass()
obj.some_method()
obj.some_method = types.MethodType(some_method_upper, obj)
obj.some_method()
Run Code Online (Sandbox Code Playgroud)
Joh*_*uhy 11
那么,类是第一类对象,因此您可以根据需要在方法中创建它们.例如
from optparse import OptionParser
def make_custom_op(i):
class MyOP(OptionParser):
def exit(self):
print 'custom exit called', i
return MyOP
custom_op_class = make_custom_op(3)
custom_op = custom_op_class()
custom_op.exit() # prints 'custom exit called 3'
dir(custom_op) # shows all the regular attributes of an OptionParser
Run Code Online (Sandbox Code Playgroud)
但是,真的,为什么不在正常水平上定义班级呢?如果需要自定义它,请将自定义作为参数放入__init__
.
(编辑:修复代码中的输入错误)
Python不直接支持这种(匿名类),但由于其简洁的语法,它并不是必需的:
class MyOptionParser(OptionParser):
def exit(self, status=0, msg=None):
# body of method
p = MyOptionParser()
Run Code Online (Sandbox Code Playgroud)
唯一的缺点是你将MyOptionParser添加到命名空间,但正如John Fouhy指出的那样,如果要多次执行,可以在函数内部隐藏它.