def gen_random_str(min_length, max_length, prefix=None, suffix=None,
                   has_letter=True, has_digit=False, has_punctuation=False):
    """
    指定一个前后缀、字符串长度以及字符串包含字符类型，返回随机生成带有前后缀及指定长度的字符串

    :param:
        * min_length: (int) 字符串最小长度
        * max_length: (int) 字符串最小长度
        * prefix: (string) 字符串前缀
        * suffix: (string) 字符串后缀
        * has_letter: (bool) 字符串时候包含字母，默认为 True
        * has_digit: (bool) 字符串是否包含数字，默认为 False
        * has_punctuation: (bool) 字符串是否包含标点符号，默认为 False

    :return:
        * random_str: (string) 指定规则的随机字符串

    举例如下::

        print('--- gen_random_str demo ---')
        print(gen_random_str(5, 7))
        print(gen_random_str(5, 7, prefix='FISHBASE_'))
        print(gen_random_str(5, 7, prefix='FISHBASE_', suffix='.py'))
        print(gen_random_str(5, 7, has_digit=True, has_punctuation=True))
        print(gen_random_str(5, 7, prefix='FISHBASE_', has_digit=True, has_punctuation=True))
        print('---')

    执行结果::

        --- gen_string_by_range demo ---
        q4uo6E8

        FISHBASE_8uCBEUH

        FISHBASE_D4wRX2.py

        FISHBASE_65nqlNs

        FISHBASE_3"uFm$s
        ---
    """
    if not all([isinstance(min_length, int), isinstance(max_length, int)]):
        raise ValueError('min_length and max_length should be int, but we got {} and {}'.
                         format(type(min_length), type(max_length)))

    if min_length > max_length:
        raise ValueError('min_length should less than or equal to max_length')

    # 避免随机源为空
    if not any([has_letter, has_digit, has_punctuation]):
        raise ValueError('At least one value is True in has_letter, has_digit and has_punctuation')

    random_str_len = random.randint(min_length, max_length)

    random_source = ''
    random_source += string.ascii_letters if has_letter else ''
    random_source += string.digits if has_digit else ''
    random_source += string.punctuation if has_punctuation else ''

    # 避免出现 ValueError: Sample larger than population or is negative
    if random_str_len > len(random_source):
        random_source *= (random_str_len // len(random_source) + 1)

    mid_random_str = ''.join(random.sample(random_source, random_str_len))

    prefix = prefix if prefix else ''
    suffix = suffix if suffix else ''

    random_str = ''.join([prefix, mid_random_str, suffix])

    return random_str
指定一个前后缀、字符串长度以及字符串包含字符类型，返回随机生成带有前后缀及指定长度的字符串

    :param:
        * min_length: (int) 字符串最小长度
        * max_length: (int) 字符串最小长度
        * prefix: (string) 字符串前缀
        * suffix: (string) 字符串后缀
        * has_letter: (bool) 字符串时候包含字母，默认为 True
        * has_digit: (bool) 字符串是否包含数字，默认为 False
        * has_punctuation: (bool) 字符串是否包含标点符号，默认为 False

    :return:
        * random_str: (string) 指定规则的随机字符串

    举例如下::

        print('--- gen_random_str demo ---')
        print(gen_random_str(5, 7))
        print(gen_random_str(5, 7, prefix='FISHBASE_'))
        print(gen_random_str(5, 7, prefix='FISHBASE_', suffix='.py'))
        print(gen_random_str(5, 7, has_digit=True, has_punctuation=True))
        print(gen_random_str(5, 7, prefix='FISHBASE_', has_digit=True, has_punctuation=True))
        print('---')

    执行结果::

        --- gen_string_by_range demo ---
        q4uo6E8

        FISHBASE_8uCBEUH

        FISHBASE_D4wRX2.py

        FISHBASE_65nqlNs

        FISHBASE_3"uFm$s
        ---