Python 3: лучший способ реализовать свой собственный тип с ограничениями - PullRequest
0 голосов
/ 17 мая 2018

Я делаю преобразование данных на основе Python 3, и к определенным символьным полям, над которыми я работаю, применяются определенные допуски символов и ограничения длины.

Я бы хотел иметь какую-то заменяемую / настраиваемуюограничивающую функцию. Я бросаю себя, что могу вызвать.

  1. Можете ли вы расширить str?
  2. Лучше ли для этого определить класс и сделать реализации переменных этого класса.

Или есть ли более простые способы сделать это с Python 3?

Мне интересно, кто-нибудь может дать мне подсказки относительно того, что Google для вдохновения?

(МойПервоначально мы должны посмотреть на внутренний код SQLAlchemy для вдохновения таких вещей, как Column).РЕДАКТИРОВАТЬ: код SQLAlchemy слишком сложен для этого сценария!


Например, тип, который допускает только:

  • буквенно-цифровые (верхний + нижний регистр)
  • числовые
  • плюс выбор специальных символов.Это может варьироваться в зависимости от поля, но некоторые могут использовать одну и ту же функцию.Отсюда желание создавать пользовательские многократно используемые типы.
  • Я сделаю зачистку или замену символов.

Тогда один может разрешить только 50 символов, а другой - 500 и т. Д.

Я передам обратно кортеж с исходным значением, преобразованным значением, логическим значением для обозначения усечения

1 Ответ

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

Вот чем я закончил:

valobj.py

import utils
class UDT:

    def __init__(self, converter, maxlen, value):
        if utils.getClassName(converter) != 'function':
            raise TypeError(f'converter {converter} is not a function')
        if int(maxlen) <= 0:
            raise TypeError(f'maxlen {maxlen} must be 1 or more')
        if utils.getClassName(value) != 'str':
            raise TypeError(f'value {value} is not a Python String')
        self.converter = converter
        self.maxlen = int(maxlen)
        self.value = value

    def convert(self):
        intermed = self.converter(self.value)
        truncated = len(intermed) > self.maxlen
        result = intermed[:self.maxlen] if truncated else intermed
        return (result, truncated, self.value)

class Job:
    def __init__(self, name):
        self._name_tuple = UDT(utils.fix_chars, 64, name).convert()

utils.py

import string
def getClassName(arg):
    return(str(type(arg)).replace("<class '","").replace("'>",""))

def fix_chars(text) -> str:
    result = ''
    for c in text:
        if ( (string.ascii_letters.find(c) != -1)
        or   (string.digits.find(c) != -1)
        or   ('._-#'.find(c) != -1)
           ):
            result += c
        else:
            result += '_'
    result = tidy_up_str(result)
    return (result)

def tidy_up_str(text) -> str:
    result = text
    result = result.replace('_-_', '_')
    while result.find('__') != -1:
        result = result.replace('__', '_')
    if result.endswith('_'):
        result = result[:-1]
    return result
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...