Заменить, если elif блок в питоне - PullRequest
1 голос
/ 11 марта 2011

Оказалось, что этот условный блок продолжает повторяться в моем коде. Есть ли другой способ сделать мою жизнь проще? Конечно, тело, которое должно быть выполнено для условия, отличается.

if self.datatype == "string":
    t = "z"
elif self.datatype == "double":
    t = "d"
elif self.datatype == "number":
    t = "i"
elif self.datatype == "blob":
    t = "z"
else:
    raise EntParEx("Unknown datatype" + self.datatype)

...... больше кода с использованием того же условного

def emit_cpp_def(self):
    s = ""
    e = ""
    if self.datatype == "string":
        s += "static const int " + self.lenvar + " = " + self.length + ";"
        s += "\nchar"
        e += "[" + self.lenvar + " + 2" + "]"
    elif self.datatype == "double":
        s += "double"
    elif self.datatype == "number":
        s += "int"
    elif self.datatype == "blob":
        s += "char*"
    else:
        raise EntParEx("Unknown datatype" + self.datatype)

    s += " " + self.cpp_membername;
    s += e
    s += ";"
    return s;

def emit_cursor_def_code(self):
    if self.datatype == "blob":
        return ""

    ret = "nvl(" + self.db_fieldname + ", "
    #TODO: Add default value loading!
    if self.datatype == "string":
        ret += "\' \'"
    elif self.datatype == "double":
        ret += "-1.0"
    elif self.datatype == "number":
        ret += "-1"
    else:
        raise EntParEx("Unknown datatype" + self.datatype)
    ret += "), "
    return ret

EDIT: Я думаю, что мне нужно что-то вроде запуска определенной функции для каждого типа. К сожалению, я не настолько разбираюсь в питоне. Это может быть сделано? т.е.

switch_datatype(function_string(), function_integer(), ...etc)

Это хуже?

Ответы [ 3 ]

15 голосов
/ 11 марта 2011

Если это точно такое же условие, вставьте его в метод и вызовите его там, где вам нужно. В противном случае определите где-нибудь словари и используйте все, что вам нужно.

datatypes = {'string': 'z', 'double': 'd', 'number': 'i', 'blob': 'z'}
t = datatypes[self.datatype]

Вы можете перехватить KeyError и вызвать исключение домена.

4 голосов
/ 11 марта 2011

Опираясь на ответ @ jleedev, если вы действительно много делаете, и , если вы хотите пользовательское исключение:

class EntParEx(KeyError): pass
class DataMapping(dict):
    def __missing__(self, key):
        raise EntParEx("unknown datatype {}".format(key))


>>> datatypes = DataMapping(string='z', double='d', number='i', blob='z')
>>> datatypes['string']
'z'
>>> datatypes['other']
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    datatypes['other']
  File "<pyshell#8>", line 3, in __missing__
    raise EntParEx("unknown datatype {}".format(key))
EntParEx: 'unknown datatype other'

Изменить, чтобы добавить код для расширенного примера:

>>> datatypes = DataMapping(string='static const int {lenvar} = {length};\nchar {cpp_membername}[{lenvar}+2];',
        double='double {cpp_membername};',
        number='int {cpp_membername};',
        blob='char* {cpp_membername};')
>>> inst = C()
>>> inst.lenvar = 'a'
>>> inst.length = 5
>>> inst.cpp_membername='member'
>>> datatypes['number'].format(**vars(inst))
'int member;'
>>> datatypes['string'].format(**vars(inst))
'static const int a = 5;\nchar member[a+2];'
1 голос
/ 11 марта 2011

Вы также можете сделать что-то более динамичное.

type(self.datatype).__name__

Возвращает "str", "float", "int" и т. Д. Вы можете взять первый символ этого.

...