在Python中可以像JavaScript一样原型化字符串函数吗
在JavaScript中,你可以这样做,把一个修剪(trim)功能添加到现有的原型函数里。
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
然后你可以像这样来使用这些功能。
trimmed = myString.trim();
这样你就得到了一个修剪过的字符串。
在Python中,我知道可以通过这样的方法列出字符串的原型函数:
print dir(myString)
但是我该怎么在Python中添加一个原型函数呢?
1 个回答
首先,Python 是基于类的对象系统,而不是像 JavaScript 那样的基于原型的系统。
给一个类或实例添加方法(或者其他属性)是非常简单的:
FooClass.method = my_method
foo_instance.method = my_method
不过,这种方法对许多“内置”类型(真正的内置类型,以及那些在 C 扩展中定义的类型)是行不通的。而 str
就是其中之一。
所以,你不能这样做。
不过,几乎任何类型都可以很容易地创建一个子类:
class MyStringType(str):
def trim(self):
# your implementation here
你可能需要一个自定义的 __init__
方法,还有可能需要一个自定义的 __new__
方法。还要确保把所有返回 str
的方法改成返回 MyStringType
。
另一种方法是通过委托来实现:
class MyStringType(object):
def __init__(self, *args, **kwargs):
self.s = str(*args, **kwargs)
def trim(self):
# your implementation here
这样,你就需要明确地转发每一个想要从 str
中获取的方法,而不是自动获取。不过,这样做通常更好。特别是考虑到你可以很简单地通过实现一个自定义的 __getattr__
,或者在 __init__
中或类级别上编写转发方法来实现。
但最简单的解决方案是……干脆别这么做。为什么要让一个 trim
函数只接受 str
类型的参数呢?
这样做的好处是,你的 trim
函数可以接受任何类似字符串的对象。例如,你的 trim
函数(作为对某个编译正则表达式 r
的 r.replace
的封装)可以同时处理 unicode
和 bytes
(在 Python 2.x 中,bytes
是 str
的同义词,而在 3.x 中则不是……但如果你能同时处理这两者,那就无所谓了),还可以处理 PyObjC 的 NSString
封装或 pywin32 的 BSTR
封装,等等。一个 find
类型的方法甚至可以在 mmap
区域上工作。为什么要限制它只能在 str
上工作呢?
这种“鸭子类型”是 Python 处理事情的核心。如果你的代码没有理由关心一个对象的实际类型,那就不必特意去关注它。