比如说:
import numpy as np
class Person:
name: str
age: int
hobbies: np.ndarray
person = Person()
person.age = "12" # raise TypeMismatched exception
Github 上面找到几个在 Python3 测试一下然而并不能用。现在开发 debug 中遇到的 10 个 需要呕心沥血 debug 的中有 9 个都是因为类型问题,镶嵌类型尤其难搞。def 虽然有 type hints,但是函数过多时会封装成这样:
class Params:
param1 = 'hello'
param2 = '...'
...
param7 = '...'
所以为了保持代码干净,最好还是在 class 里加入类型的检查。大家除了 IDE、眼球 parse 和记忆力还有什么好办法?
1
Tyanboot 2018-07-26 00:13:05 +08:00
类型标注这个只有在 3.6 及以上的版本才支持的. 解决办法就是升级你的 python 到 3.6
|
2
so1n 2018-07-26 00:32:47 +08:00 via Android 1
有个叫 attrs 的库
|
3
ligyxy 2018-07-26 01:12:26 +08:00 via Android
Data Classes
|
4
Cbdy 2018-07-26 08:25:22 +08:00 via Android
换有类型的语言
|
5
araraloren 2018-07-26 08:51:54 +08:00
可选类型的语言是多么明智。。
|
6
netfee 2018-07-26 09:40:26 +08:00 via Android 1
class People:
def __init_(self, name: str=None, age: int=0) ->None: --- def find_all_people() ->[People]: --- 这样实现类型注释,方便 ide 预检查错误,参考 pep 484 type hint https://www.python.org/dev/peps/pep-0484/ Python 3.5 就提供这种语法支持了。而当前主流 Linux 发行版预置的 Python3 都是 3.5+以上版本了,所以真的可以全面转到 py3 了。到 V3.6 还提供 f-string 语句支持( pep 498 )。 |
7
zhuangzhuang1988 2018-07-26 09:59:52 +08:00
换语言
|
8
xpresslink 2018-07-26 10:05:45 +08:00 1
有个比较 lowbility 但是有效的办法就是,在函数或类最开始
就把要用到所有变量名加上类型前缀或后缀并赋初始值,比如下面这样: def foo(): int_a = 0, a_int=0 , str_b='', b_str='' 过程中严禁同一变量名改换类型使用,这样 IDE 就可以比较好的类型推断了。 不过这样写 python 的话还不如直接用够浪( golang ) |
9
karllynn 2018-07-26 11:20:25 +08:00
升级到最新的 Python
或者不用在意类型,用的时候强制转换就行了…比如这个 age,你先 age = int(p.age)不就完了 |
10
Philippa OP 当把 object 作为参数时,python3.6 是不能检查 object 的 attr 的类型的。变量名包括类型已经有了,然而变量多层传递后也不会有大的作用。因此:
``` class Person: name: str age: int ``` 以上这种语法是无效的,Python3.6 也根本不支持这种语法,我不知道大家回答这个是因为误解了还是不知道这一点。 但下面这一个可以。 ``` class TypeMismatched(Exception): pass class Person: def __init__(self, name: str, age: int): self.name = name self.age = age def __setattr__(self, name, value): # Invalid for class comparsion if hasattr(self, name) and type(self.__dict__[name]) != type(value): raise TypeMismatched self.__dict__[name] = value person = Person(name='Jane', age=12) print(person.name) print(person.age) person.age = '14' print(person.age) # raise TypeMismatched Exception ``` 因此想了想,用 type hints 作为 class 属性的首次检查,重载__setattr__,加入检查方法,作为以后 mutable 值的检查。上面的 type(variable_a) == type(variavble_b)有缺陷,需要再改进一下,但基本思路就这样了。 |
11
Philippa OP 为什么 markdown 不能用……
|
12
Philippa OP 可以在 class 里面加入一个参数, 虽然有点不雅观,mutable -> bool 来决定是否 mutable。一样地,在__setattr__里面做检查。
|
13
Philippa OP @xpresslink 换语言不是说换就换了,写 numpy 的话 golang 怎么写…… postfix 加类型的做法已经实行很久了,但效果有限,尤其对镶嵌类型的 list 等,numpy 有太多自定义类型,然而 python 本身却不可标注,再加上镶嵌,灾难就发生了
|
14
Philippa OP @karllynn 每次都 int(age)这样太丑了,妨碍其他人阅读你的代码,code review 肯定不让过,而且影响性能(虽说不大)。
|
15
GoLand 2018-07-26 13:03:18 +08:00 1
pydantic 了解一下。还有校验功能。结合 mypy 使用。
|
16
Philippa OP @GoLand 谢谢,这个库有些有用的工具可以用来自己封装。因为测试后发现,初始化为 str 后赋予 int 还是不会抛 error。当传入错误的类型,希望程序能够崩溃。
|
17
linkermlin 2018-11-19 18:10:16 +08:00
不编译检查了又能怎么样呢?
还是 Cython 靠谱。推荐了解下。 |