专栏名称: 王建硕
王建硕的微信。
目录
相关文章推荐
云南省广播电视局  ·  省广电局主要负责同志开展2025年政务服务走 ... ·  18 小时前  
云南省广播电视局  ·  省广电局主要负责同志开展2025年政务服务走 ... ·  18 小时前  
GevinView  ·  扣子空间:重新定义 AI ... ·  昨天  
GevinView  ·  扣子空间:重新定义 AI ... ·  昨天  
51好读  ›  专栏  ›  王建硕

我刚写的 216 行代码的开源项目 Piiwee

王建硕  · 公众号  · 科技自媒体  · 2023-08-21 08:47

正文

请到「今天看啥」查看全文




def expr(exp: Union[ast.AST, Expression, str], model: Model) -> Expression: """Convert an ast expression to a peewee expression
I am surprised that no one actually created this function.
>>> from peewee import CharField, IntegerField >>> class User(Model): ... name = CharField() ... age = IntegerField() >>> expr("name == 'John' and age > 18", User) # doctest: +ELLIPSIS
Args: exp (Union[ast.AST, Expression, str]): _description_ model (Model): _description_
Raises: NotImplementedError: Not all ast expressions can map to peewee expressions. Raise this error if the ast expression is not supported yet.
Returns: Expression: The peewee Expression """ if isinstance(exp, str): return expr(ast.parse(exp, mode="eval").body, model) if isinstance(exp, ast.Constant): return exp.value if isinstance(exp, ast.Name): return getattr(model, exp.id) if isinstance(exp, (ast.Tuple, ast.List)): return [expr(e, model) for e in exp.elts] if isinstance(exp, ast.UnaryOp): return ( expr(exp.operand, model).desc() if isinstance(exp.op, ast.USub) else expr(exp.operand, model).asc() ) if isinstance(exp, ast.BoolOp): elements = [expr(e, model) for e in exp.values] return ( reduce(operator.and_, elements) if isinstance(exp.op, ast.And) else reduce(operator.or_, elements) ) if isinstance(exp, ast.Compare): return Expression( expr(exp.left, model), operator_name(exp.ops[0]), expr(exp.comparators[0], model), ) raise NotImplementedError(f"Expression [{exp}] not supported yet")

def ensure_tuple(data) -> tuple: """Ensure the output is a tuple
>>> ensure_tuple(1) (1,)
>>> ensure_tuple([1, 2]) (1, 2)
>>> ensure_tuple((1, 2)) (1, 2)
Args: data (any): any data
Returns: tuple: make sure the output is a tuple """ if isinstance(data, (list, tuple)): return tuple(data) return (data,)

def field_eq( exp: Union[Expression, Field], field: Union[Field, str] ) -> Union[str, None]: """Get the value from the expression for the specified fields. For example, expression reprsentation of "a = 1 AND b = 2", and field = a will return "1".
>>> from peewee import CharField, IntegerField >>> class User(Model): ... name = CharField() ... age = IntegerField() >>> field_eq(Expression(User.name, "=", "John"), "name") 'John'
>>> field_eq(Expression(Expression(User.name, "=", "John"), ... 'AND', ... Expression(User.age, "=", 18)), "age") 18
Args: exp (Union[Expression, Field]): The expression to get the value from field (Union[Field, str]): The name or Field representing the field
Returns: str | None: the value of the field, or None if not found """ if isinstance(exp, Expression): if exp.op == "AND": return field_eq(exp.lhs, field) or field_eq(exp.rhs, field) if exp.op == "=": return exp.rhs if exp.lhs.name in field_names([field])[0] else None return None

def field_names(fields: List[Union[Field, str]]) -> List[str]: """Get the string names of the fields
>>> field_names(["a", "b"]) ['a', 'b']
>>> from peewee import CharField, IntegerField >>> class User(Model): ... name = CharField() ... age = IntegerField() >>> field_names([User.name, User.age]) ['name', 'age']
Args: fields (List[Union[Field, str]]): The fields to get the names from
Returns: List[str]: A list of string names of the fields """ return [f.name if isinstance(f, Field) else f.strip() for f in fields]

def all_combinations(names: List[str]) -> List[tuple]: """Generate all combinations of the names, from empty set, to two, three or more elements of combinations, until the result is the same length as the list.
>>> list(all_combinations(["a", "b"])) [(), ('a',), ('b',), ('a', 'b')]
>>> list(all_combinations([])) [()]
Args: names (List[str]): The elements to generate combinations from
Yields: List[tuple[str]]: The combinations of the names """ for i in range(len(names) + 1): yield from combinations(names, i)

def md5(data: str) -> str: """Generate the md5 hash of the data
Args: data (str): The data
Returns: str: The md5 hash """ return hashlib.md5(data.encode("UTF-8")).hexdigest()

def flat(items: dict, sep: str = "=", join: str = ":") -> str: """Flatten a dictionary to a string. Key and value are separated by `sep`, and each key-value pair is separated by `join`.
>>> flat({"a": 1, "b": 2}) 'a=1:b=2'
>>> flat({"a": 1, "b": 2}, sep=":", join="=") 'a:1=b:2'
Args: items (dict): the dictionary to flatten sep (str, optional): the seperator. Defaults to "=". join (_type_, optional): the joiner. Defaults to ":".
Returns: str: the flattened string """ items = items or {} return join.join([f"{key}{sep}{value}" for key, value in items.items()])

def getattrs(obj: Union[dict, object, Expression], names: List[str]) -> dict: """A helper to get the attributes from an object, a dict or an peewee expression.
>>> getattrs({"a": 1, "b": 2, "c": 3}, ["a", "b"]) {'a': 1, 'b': 2}
>>> class User: ... def __init__(self, name, age): ... self.name = name ... self.age = age





请到「今天看啥」查看全文