Python,根据输入字符串的格式和内容运行一个函数

时间:2010-12-15 00:00:57

标签: python string-comparison

我以为我会尝试编写一种仅用于练习的测量单位转换。 我希望它的工作方式是为用户提供单个输入提示,并根据字符串运行相应的函数。

我只是想知道什么是告诉天气的最佳方式,字符串格式如下:

数字单位

示例: 30厘米英寸(这将运行名为 cmtoinch 的函数,将数字30作为争论传递)。

我还需要能够分辨哪个单位在另一个原因之前,“30厘米英寸”会产生不同的结果,然后是“30英寸厘米”。

我在想我会将每个单元的名称放入列表中,但我不知道如何将字符串与列表进行比较以查看它是否包含至少两个值。

5 个答案:

答案 0 :(得分:4)

在字符串上使用.split()将其分解为单词(然后您可以根据需要将第一个重新解释为intfloat)。结果列表的顺序与输入字符串的顺序相同,因此您可以依次查看每个元素,并根据您的参考单元列表进行检查。

为每次转换创建单独的函数可能不是您想要做的。相反,将输入转换为某个公共单位,然后从公共单位转换为所需的输出单位。为此,我们将每个单元与单个转换因子相关联;我们乘以第一次,然后再划分第二次。

要在单位名称和转换值之间建立关联,我们使用dict。这使我们可以通过插入名称直接查找转换值。

conversion_rates = {
    'in': 2.54, # 2.54 inches in a centimetre
    'cm': 1.00, # this is our reference unit
    'sun': 3.03 # a traditional Japanese unit of measurement
}

# raises ValueError if the number of words in the input is wrong
amount, original_unit, final_unit = line.split()

# raises ValueError if the amount is not formatted as a floating-point number
amount = float(amount)

# Now we do the conversion.
# raises KeyError if either unit is not found in the dict.
result = amount * conversion_rates[original_unit] / conversion_rates[final_unit]

答案 1 :(得分:3)

根据此代码的组织结构,您可能需要在此处使用globals()<modulename>.__dict__getattr(obj)。我的示例使用globals()

def cmtoinch(x):
  return x / 2.54

def inchtocm(x):
  return x * 2.54

def convert(input):
  num, unit1, unit2 = input.split()
  func = unit1 + "to" + unit2
  if func in globals():
    return globals()[func](float(num))
  else:
    raise NotImplementedException()

答案 2 :(得分:2)

您可以使用字典(映射),并利用您使用元组作为键的事实。

#!/usr/bin/python2

import sys

def inch2cm(inches):
    return inches * 2.54

def cm2inch(cm):
    return cm / 2.54


DISPATCH_TABLE = {
    ("in", "cm"): inch2cm,
    ("cm", "in"): cm2inch,
}

def converter(argv):
    """converter <value> <from unit> <to unit>
    """
    try:
        value = float(argv[1])
        unit_from = argv[2]
        unit_to = argv[3]
    except (ValueError, IndexError), ex:
        print ex
        print converter__doc__
        return 2

    func = DISPATCH_TABLE[(unit_from.lower()[:2], unit_to.lower()[:2])]
    print func(value)

    return 0


sys.exit(converter(sys.argv))

不是说这是进行单位转换的最佳方式,而只是演示调度功能。

我比从globals()中选择更好,因为它更明确,更安全。

答案 3 :(得分:0)

{
    'cm': {
        'inch': cmtoinch,
        'microparsec': cmtomicroparsec
    }
}

答案 4 :(得分:0)

这是怎么回事?

class Translator():
    UNITS = [
        # length
        {
            "cm": 1.0,
            "inch": 2.54,
            "foot": 30.48,
            "rod": 502.92
        },
        # weight
        {
            "kg": 1.0,
            "pound": 0.454,
            "stone": 6.356
        },
        # liquid volume
        {
            "litre": 1.0,
            "pint": 0.473,
            "gallon": 3.785
        }
    ]

    def translate(self, val, unit1, unit2):
        for u in Translator.UNITS:
            if u.has_key(unit1) and u.has_key(unit2):
                return float(val) * u[unit1] / u[unit2]

        return "Can't convert from %s to %s" % (unit1, unit2)

    def translateString(self, str):
        args = str.split()
        if len(args)==3:
            return self.translate( float(args[0]), args[1], args[2] )
        else:
            return "Exactly three arguments required!"

def main():
    t = Translator()

    while True:
        inp = raw_input("Translate what? (hit Enter to quit) ")
        if len(inp) > 0:
            t.translateString(inp)
        else:
            break