Моя идея программы:
У меня есть словарь:
options = { 'string' : select_fun(function pointer),
'float' : select_fun(function pointer),
'double' : select_fun(function pointer)
}
независимо от типа вызывается одна функция select_fun(function pointer).
Внутри select_fun(function pointer) у меня будут функции diff для float, double и так далее.
В зависимости от указателей на функции будет вызвана указанная функция.
Я не знаю, хорошие у меня знания программирования или плохие, но мне нужна помощь.






Не могли бы вы уточнить, что вы пытаетесь сделать? Вам не нужно делать ничего особенного, чтобы получить указатели на функции в Python - вы можете передавать функции как обычные объекты:
def plus_1(x):
return x + 1
def minus_1(x):
return x - 1
func_map = {'+' : plus_1, '-' : minus_1}
func_map['+'](3) # returns plus_1(3) ==> 4
func_map['-'](3) # returns minus_1(3) ==> 2
Ваш ответ уместен. Но в случае 3 в качестве параметра я передаю указатель на функцию, который вызывает определенную функцию внутри select_fun.
@ rejinacm.myopenid.com: вы по-прежнему не используете "указатели". Вы просто используете функцию как объект. Нет указателя. Просто передайте функцию.
Раньше я использовал эту стратегию. Мне это показалось более медленным при выполнении, вероятно, когда функция начала значение dict, которое оно недавно скопировало в память, вместо того, чтобы работать как указатель. Есть какие-нибудь комментарии по этому поводу?
Вы можете использовать type() встроенная функция для определения типа функции.
Скажем, если вы хотите проверить, содержит ли определенное имя строковые данные, вы можете сделать это:
if type(this_is_string) == type('some random string'):
# this_is_string is indeed a string
Итак, в вашем случае вы могли бы сделать это так:
options = { 'some string' : string_function,
(float)(123.456) : float_function,
(int)(123) : int_function
}
def call_option(arg):
# loop through the dictionary
for (k, v) in options.iteritems():
# if found matching type...
if type(k) == type(arg):
# call the matching function
func = option[k]
func(arg)
Тогда вы можете использовать это так:
call_option('123') # string_function gets called
call_option(123.456) # float_function gets called
call_option(123) # int_function gets called
У меня поблизости нет интерпретатора Python, и я не очень много программирую на Python, поэтому могут быть некоторые ошибки, но вы должны уловить идею.
Обновлено: Согласно предложению @ Adam, существуют встроенные константы типов, которые можно проверять напрямую, поэтому лучшим подходом будет:
from types import *
options = { types.StringType : string_function,
types.FloatType : float_function,
types.IntType : int_function,
types.LongType : long_function
}
def call_option(arg):
for (k, v) in options.iteritems():
# check if arg is of type k
if type(arg) == k:
# call the matching function
func = options[k]
func(arg)
А поскольку сам ключ сопоставим со значением функции type (), вы можете просто сделать это:
def call_option(arg):
func = options[type(arg)]
func(arg)
Что более элегантно :-) за исключением проверки ошибок.
Обновлено: И для поддержки ctypes после некоторой игры я обнаружил, что ctypes. [Type_name_here] фактически реализован как классы. Так что этот метод все еще работает, вам просто нужно использовать классы типа ctypes.c_xxx.
options = { ctypes.c_long : c_long_processor,
ctypes.c_ulong : c_unsigned_long_processor,
types.StringType : python_string_procssor
}
call_option = lambda x: options[type(x)](x)
Хотя технически правильно, я бы сказал, что было бы лучше сравнивать константы types.FloatType, types.StringType и types.IntType в модуле типов.
call_option = лямбда-аргумент: параметры [тип (аргумент)] (аргумент)
для беззнакового или подписанного типа, что мне делать?
Как вы получаете беззнаковый тип в Python?
Я вызываю dll, написанную на VB. Я проверяю ее тип и затем конвертирую соответственно. В pyhton есть основные типы данных ctypes, которые имеют вышеуказанное. Я хочу знать, как двигаться дальше ...
Может быть, вы хотите каждый раз вызывать один и тот же select_fun() с разными аргументами. Если вы это имеете в виду, вам нужен другой словарь:
>>> options = {'string' : str, 'float' : float, 'double' : float }
>>> options
{'double': <type 'float'>, 'float': <type 'float'>, 'string': <type 'str'>}
>>> def call_option(val, func):
... return func(val)
...
>>> call_option('555',options['float'])
555.0
>>>
Просто пытаюсь понять исходный вопрос, заданный в терминах call_option ().
Функции являются первоклассными объектами в Python, поэтому вы можете передавать их в качестве аргументов другим функциям, как и любой другой объект, такой как строка или целое число.
В Python нет типа с плавающей запятой одинарной точности. float Python соответствует double C.
def process(anobject):
if isinstance(anobject, basestring):
# anobject is a string
fun = process_string
elif isinstance(anobject, (float, int, long, complex)):
# anobject is a number
fun = process_number
else:
raise TypeError("expected string or number but received: '%s'" % (
type(anobject),))
return fun(anobject)
Существует functools.singledispatch, позволяющий создать универсальную функцию:
from functools import singledispatch
from numbers import Number
@singledispatch
def process(anobject): # default implementation
raise TypeError("'%s' type is not supported" % type(anobject))
@process.register(str)
def _(anobject):
# handle strings here
return process_string(anobject)
process.register(Number)(process_number) # use existing function for numbers
В Python 2 аналогичная функциональность доступна как pkgutil.simplegeneric().
Вот пара примеров кода использования универсальных функций:
Глядя на ваш пример, мне кажется, что это какая-то процедура C, напрямую переведенная на Python.
По этой причине я думаю, что может быть некоторая проблема с дизайном, потому что обычно в Python вас не волнует тип объекта, а только сообщения, которые вы можете ему отправить.
Конечно, есть много исключений из этого подхода, но все же в этом случае я бы попытался инкапсулировать в некоторый полиморфизм; например.
class StringSomething(object):
data = None
def data_function(self):
string_function_pointer(self.data)
class FloatSomething(object):
data = None
def data_function(self):
float_function_pointer(self.data)
и т.п.
Опять же, все это в предположении, что вы переводите с процедурного языка на Python; если это не так, то откажитесь от моего ответа :-)
В Python почти никогда не требуется специфичная для типа обработка. Кроме того, поскольку select_fun (aFunction) каждый раз одно и то же, неясно, какой смысл в get select_fun (aFunction) из словаря.