python: динамическое приведение типов - преобразование объекта Unicode в объект Python - PullRequest
0 голосов
/ 03 мая 2018

Это проблема, с которой я сталкиваюсь для проекта конвейера данных. У меня есть 2 источника данных. Один содержит все пользовательские данные, другой содержит метаданные о том, что все столбцы мы должны обработать от пользовательских данных до вывода.

Так что Python хорош с динамическим приведением типов, как если бы я сказал

a = float
b = "25.123"
c = a(b)
print(c)
>> 25.123

Это то, что я хочу сделать, я хочу динамически печатать приведенные значения для их правильной обработки. Тип извлекается из источника данных метаданных. Проблема заключается в том, что когда я выполняю запрос модели django к метаданным, я получаю объекты Unicode.

a = model.objects.filter(id = 'id') # get the type variable from the meta-data
a = a[0]['type']
print(a)
>> u'float'
a("123.123")
>> TypeError: 'unicode' object is not callable

Как мне преобразовать этот u'float 'в float? Есть ли у этого подхода лучшие альтернативы? Я проверил это , но оно не работает

Открыто для всех предложений

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

В вашем первом примере, где a = float, a - встроенная функция, а во втором - a = u"float", a - строка в кодировке Unicode. Если вы хотите, чтобы полная «динамичность» встроенного типа конвертировалась без необходимости создания отображения, вы можете сделать это:

# for Python 2
a = u"float"
b = "123.123"
import __builtin__
print getattr(__builtin__, a.decode())(b) 
# 123.123

# for Python 3+
a = u"float"
b = "123.123"
import builtins
print(getattr(builtins, a)(b))
# 123.123

Я бы посоветовал вам не использовать eval() (как предлагает другой ответ ), поскольку это может привести к серьезным рискам безопасности. Вот почему я использовал модуль __builtin__ / builtins и getattr() для получения функции float(...).


Вы также можете создать отображение (т. Е. A dict) для сопоставления строки Юникода с соответствующей функцией (предложенной этим комментарием ):

# both Python 2 and 3
a = u"float"
b = "123.123"
mapping = {u"float": float, u"int": int, u"str": str, u"list": list}
print(mapping[a](b))
# 123.123

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

0 голосов
/ 03 мая 2018

Вы можете использовать astype из библиотеки numpy:

import numpy as np
np.array(('213.123')).astype(a)

по общему признанию, это должно пройти через массив, потому что astype() работает на numpy-массивах - но он может вычислять строку как тип.

0 голосов
/ 03 мая 2018

Вы можете использовать функцию eval() для оценки кода, но вы должны быть осторожны с этой функцией! В противном случае, вы можете взглянуть на этот пост . Другое решение состоит в том, чтобы предварительно определить разрешенные типы и собрать их в словарном отображении typeName с typeConstructor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...