起因
在一些函数中,我们有时候只想要指定的几个输入,但是在代码/函数 交给别人使用的时候,别人还需要看文档,甚至不知道该传什么值,这个有一点不友好。
所以,我们想在代码中定义一些常量,供代码使用者调用。
使用变量
# const.py
CAT = 'cat'
DOG = 'dog'
这个时候,我们就可以使用了
import const
const.CAT
嗯。。。。。这个时候我们又有一个类型了
# const.py
CAT = 'cat'
DOG = 'dog'
MAC = 'mac'
WIN = 'windows'
LINUX = 'linux'
我们再来看一下
???(黑人问号脸),改选哪一个,CAT 是什么鬼?
使用类 + property
现在的常量代码如下
# const.py
class _Animal(object):
@property
def cat(self):
return 'cat'
@property
def dog(self):
return 'dog'
class _Platform(object):
@property
def mac(self):
return 'mac'
@property
def win(self):
return 'windows'
@property
def linux(self):
return 'linux'
Animal = _Animal()
Platform = _Platform()
嗯。。很好,现在有了刚刚吐槽的 分类
的功能。
不过有一天,有一个二货改了你的常量!!!
const.Platform.mac = 'windows'
你是不是是不是傻了?
不过这是不可能的,嘿嘿,因为没有设置 @mac.setter
修饰器的方法!
但是呢,这里还有一个问题,就是这代码也太长了吧,为了定义一个常量,需要 3 行代码,假如有 20 个常量呢。。。不仅写起来麻烦,看代码也很烦啊!!
使用类修饰器
# const.py
class _Platform(object):
mac = 'mac'
windows = 'windows'
linux = 'linux'
Platform = _Platform()
代码是减了不少,但是值可以改变。所以为了避免这样的情况,需要给类加一个修饰器~
# const.py
from functools import wraps
def Const(cls):
@wraps(cls)
def new_setattr(self, name, value):
raise Exception('const : {} can not be changed'.format(name))
cls.__setattr__ = new_setattr
return cls
@Const
class _Platform(object):
mac = 'mac'
windows = 'windows'
linux = 'linux'
Platform = _Platform()
最终的代码
# const.py
from functools import wraps
def Const(cls):
@wraps(cls)
def new_setattr(self, name, value):
raise Exception('const : {} can not be changed'.format(name))
cls.__setattr__ = new_setattr
return cls
@Const
class _Animal(object):
cat = 'cat'
dog = 'dog'
@Const
class _Platform(object):
mac = 'mac'
windows = 'windows'
linux = 'linux'
@Const
class _Const(object):
animal = _Animal()
platform = _Platform()
CONST = _Const()