简体   繁体   中英

Python type hinting for upper vs lower-cased strings?

In Python, if I am creating a list of strings, I would type hint like this:

from typing import List
list_of_strings : List[str] = []
list_of_strings.append('some string')
list_of_strings.append('some other string')

Is there some way to type hint the expected case of the strings? That way, when I write a comparison operator to search for a specific string, for example, I don't accidentally search for the mixed or upper-cased version of a string I know will be lower-cased because all strings in list_of_strings should be lower-cased. I realize I can just add comments and refer back to the list's declaration, but I was wondering if there was a more integrated way to do it.

An alternate way to solve this problem would be to make a class which extends str and rejects any values which aren't in the proper case, and then type hint for that class. Is there any reason why this would be a bad idea aside from it being more of a pain to create than a simple string?

The reason I run into this problem, is that I create lists, dicts, and other structures to store data, then need to add to or search them for a particular key/value and not knowing the expected case creates problems where I add duplicate entries because a simple if 'example' in string_list doesn't find it. And doing if 'example'.upper() in string_list is easy to forget and not very pretty. Jumping back and forth between the declaration (if I wrote a comment there describing expected case) and where I'm coding distracts from my flow, it would be nice to have the information when I'm referencing that object later.

You can in Python 3.10 using typing.TypeGuard .

from typing import TypeGuard


class LowerStr(str):
    '''a dummy subclass of str, not actually used at runtime'''


def is_lower_str(val: str) -> TypeGuard[LowerStr]:
    return val.islower()


l: list[LowerStr] = []


def append(lst: list[LowerStr], v: str):
    if not is_lower_str(v):
        raise TypeError('oh no')
    lst.append(v)

You could indeed enforce runtime safety using a subclass of str . The disadvantage would mostly be performance. You would want to take care to not add an unnecessary __dict__ , by adding __slots__ = () to the class definition, from the top of my head.

Either way, string literals are not going to be validated automatically, so it will cause some overhead, either by calling the typeguard, passing them to the constructor of the subtype, or using cast(LowerStr, 'myliteral') .

No, I've been searching on the net for this but it doesn't exist.

The Python's typing module doesn't provide any hint for lowercase or uppercase str ings.


[...] type hint the expected case of the strings

Remember that a type is for example str , and in this case you should be talking about hint and not about type hint .


You can anyway create a custom class in this scope:

class UppercaseString(str): pass

The UppercaseString will inherit all the functionalities of the built-in class str (that's what happens when you specify : pass in class declaration).

You can anyway create an instance 's method that checks if the string is really uppercase, and otherwise raises an error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM