在Java中,您可以使用匿名内部类定义新的内联类.当您只需要重写该类的单个方法时,这非常有用.
假设您要创建一个子类OptionParser
,只覆盖一个方法(例如exit()
).在Java中,您可以编写如下内容:
new OptionParser () { public void exit() { // body of the method } };
这段代码创建了一个匿名类,OptionParser
它只扩展和覆盖该exit()
方法.
Python中有类似的习惯用法吗?在这些情况下使用哪种成语?
您可以使用type(name, bases, dict)
内置函数动态创建类.例如:
op = type("MyOptionParser", (OptionParser,object), {"foo": lambda self: "foo" }) op().foo()
由于OptionParser不是新式类,因此必须明确包含object
在基类列表中.
Java主要使用匿名类来模仿闭包或简单地编写代码块.因为在Python中你可以很容易地传递方法,所以不需要像匿名内部类那样笨重的构造:
def printStuff(): print "hello" def doit(what): what() doit(printStuff)
编辑:我知道这不是这个特例所需要的.我刚刚描述了Java中匿名内部类最常见的python解决方案.
您可以通过三种方式完成此任务:
适当的子类(当然)
您以对象作为参数调用的自定义方法
(您可能想要的) - 向对象添加新方法(或替换现有方法).
选项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()
那么,类是第一类对象,因此您可以根据需要在方法中创建它们.例如
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
但是,真的,为什么不在正常水平上定义班级呢?如果需要自定义它,请将自定义作为参数放入__init__
.
(编辑:修复代码中的输入错误)
Python不直接支持这种(匿名类),但由于其简洁的语法,它并不是必需的:
class MyOptionParser(OptionParser): def exit(self, status=0, msg=None): # body of method p = MyOptionParser()
唯一的缺点是你将MyOptionParser添加到命名空间,但正如John Fouhy指出的那样,如果要多次执行,可以在函数内部隐藏它.
Python可能有更好的方法来解决您的问题.如果您可以提供有关您想要做的更具体的细节,那将有所帮助.
例如,如果需要在代码中的特定点更改被调用的方法,可以通过将函数作为参数传递来实现(函数是python中的第一类对象,可以将它们传递给函数等).您还可以创建匿名lambda
函数(但它们仅限于单个表达式).
此外,由于python非常动态,你可以在创建对象之后更改它的方法object.method1 = alternative_impl1
,虽然它实际上有点复杂,请参阅gnud的回答