【问题标题】:Is it possible to extend a Python class without the use of inheritance是否可以在不使用继承的情况下扩展 Python 类
【发布时间】:2012-08-11 15:13:40
【问题描述】:

例如,

扩展字符串类,以便打印它会在它前面加上一个制表符或一些空格。然后能够调用它,

print 'hello world'

当在标准输出上看到时,会在前面加上制表符(空白)。

【问题讨论】:

标签: python class inheritance io monkeypatching


【解决方案1】:

是:编辑 Python 的源代码。

说真的:与任何其他编程模型(结构化、OO、建模)一样,Python 对您可以做的事情施加了一些限制。虽然其中一些可能会让人觉得武断或“愚蠢”,但它们中的每一个都有充分的理由(通常是所有其他解决方案的缺点或过去的错误,如果不破坏所有现有代码就无法再修复)。

当你觉得你需要打破规则时,退后一步考虑一下:也许你的“解决方案”是错误的?也许有更好的方法来实现你想要的?

在这种情况下,使用格式:

f = '\t%s'
print f % 'hello world'

与您的解决方案不同,这明确传达了您尝试实现的目标。

也就是说,您可以使用“monkey patching”所使用的技术。请注意,这种技术是危险的。在大多数情况下,这意味着使用该技术的人不知道自己在做什么。

【讨论】:

  • 真的可以猴子补丁内置吗?当我尝试将str.__str__ 分配给其他东西时,我得到TypeError: can't set attributes of built-in/extension type 'str'。并不是说这是一个好主意——我同意你的警告——我只是出于对 Python 工作原理的好奇而尝试并询问。
  • 如果您还没有迷上旧的% 格式,我建议您使用新的str.format 格式。毕竟,这是一个改进的替代品。像这样:"\t{0}".format("hello world").
  • 谢谢,猴子补丁听起来很有趣。上面只是一个例子,我不想详细说明我在做什么。我只是想知道这种语言有什么可能
  • @Ghopper21:这是猴子补丁的另一个问题:它不适用于所有类型。
  • Monkeypatching 不适用于内置插件。它这样做了,并且在 Ruby 中被滥用,但在 Python 中却没有。
【解决方案2】:

您要更改字符串类,还是只是要更改print 的行为?如果你:

from __future__ import print_function

(或者使用Python 3)你可以提供自己的print函数,例如:

def print(*line, **kwargs):

    args = dict(sep=' ', end='\n', file=None)
    args.update(kwargs) 

    sep  = args['sep']
    end  = args['end']
    file = args['file']

    newlist = [];

    for userln in line:
        newlist.append("\t"+userln)  # prefix the line with a tab

    if file == None:
        file = sys.stdout

    __builtin__.print(sep.join(newlist),end=end,file=file)

【讨论】:

  • 我认为这只是一个例子,他问的是关于扩展 Python 类的不同可能性的更一般的问题。
猜你喜欢
  • 2016-03-11
  • 2021-01-06
  • 2015-03-22
  • 2013-09-26
  • 1970-01-01
  • 2019-12-21
  • 1970-01-01
  • 2016-03-06
  • 2022-01-15
相关资源
最近更新 更多