Python中处理不同类型的规范方法是什么?

2024-05-02 16:24:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个函数,我需要为我调用的另一个程序生成不同的输出字符串,这取决于它想要的类型。在

基本上,被调用的程序需要一个命令行参数,告诉它是用哪种类型调用的。在

很高兴我找到了this answer等如何检查变量的类型。但我注意到人们也提出了反对意见,即检查类型会暴露“非面向对象”的设计。那么,有没有其他方法,假设更“面向对象”的方式来处理这个问题,而不显式地检查类型?在

我现在的代码是这样的:

def myfunc(val):
    cmd_type = 'i'
    if instance(val, str):
        cmd_type = 's'

    cmdline = 'magicprogram ' + cmd_type + ' ' + val
    Popen(cmdline, ... blah blah)
    ...

这很好用,但我只是想知道是否有我不知道的技巧。在


Tags: 函数字符串命令行answer程序cmd类型参数
3条回答

您可以使用Double Dispatch或{a2}。在

    But I noticed how people also raised objections, 
that checking for types betrays a "not object oriented" design

实际上,它被称为Duck typing style(“如果它看起来像鸭子,并且嘎嘎叫起来像鸭子,那么它一定是鸭子。”),而且python语言推荐使用这种编程风格。在

在duck输入时,会有一些东西叫EAFP(请求原谅比允许更容易)

^{pr2}$

你的意思是更多的Python,基本上在你的情况下,更多的Python是这样的:

def myfunc(val):
    cmd_type = 'i'

    # forget about passing type to your magicprogram
    cmdline = 'magicprogram  %s ' % val 
    Popen(cmdline, ... blah blah)

在你的魔法程序里(我不知道是你的剧本还是…),因为 在所有的情况下,你的程序都会得到一个字符串,所以试着把它转换成 脚本接受

from optparse import OptionParser

# ....

if __name__ == '__main__':

    parser = OptionParser(usage="blah blah")

    # ...
    (options, args) = parser.parse_args()

    # Here you apply the EAFP with all type accepted.
    try:
        # call the function that will deal with if arg is string
        # remember duck typing.
    except ... :
        # You can continue here

我不知道你的代码都是什么,但是你可以按照上面的例子来做,它更像Python,记住每个规则都有例外,所以也许你的例子就是个例外 你最好做类型检查。在

希望这能为你澄清一切。在

我不认为双重分派或多重方法有什么特别的相关性,也与人们对另一方的反对意见没有多大关系。在

毫不奇怪,为了使您所做的事情更加面向对象,您需要在其中引入一些对象(和相应的类)。使每个值成为一个类的实例将允许——事实上,实际上是强制——您停止检查其类型。下面对示例代码的修改显示了一种非常简单的方法:

class Value(object):
    """ Generic container of values. """
    def __init__(self, type_, val):
        self.type = type_   # using 'type_' to avoid hiding built-in
        self.val = val

def myfunc(val):
    # Look ma, no type-checking!
    cmdline = 'magicprogram {obj.type} {obj.val}'.format(obj=val)
    print 'Popen({!r}, ... blah blah)'.format(cmdline)
    # ...

val1 = Value('i', 42)
val2 = Value('s', 'foobar')

myfunc(val1)  # Popen('magicprogram i 42', ... blah blah)
myfunc(val2)  # Popen('magicprogram s foobar', ... blah blah)

如果在Value类中有方法间接地访问其属性,那么它将更加面向对象,但仅执行上述操作就可以消除臭名昭著的类型检查。更面向对象的设计可能会为每种类型的Value有一个不同的子类,这些子类都为客户机(如myfunc())共享一组公共方法,用于创建、操作和从中提取信息。在

使用对象的另一个好处是,如果/当您向应用程序添加对新类型“Value”的支持时,您不必修改myfunc()如果您对“Value”本质的抽象是好的,也就是说。在

相关问题 更多 >