sensitive_words_list = ['asshole', 'fuck', 'shit']
def detect_sensitive_words(string):
'''检测敏感词汇'''
words_detected = filter(lambda word: word in string.lower(), sensitive_words_list)
if words_detected:
raise NameError('Sensitive words {0} detected in the string "{1}".' \
.format(
', '.join(map(lambda s: '"%s"' % s, words_detected)),
string
)
)
class CleanerMeta(type):
def __new__(cls, class_name, bases, attrs):
detect_sensitive_words(class_name) # 检查类名
map(detect_sensitive_words, attrs.iterkeys()) # 检查属性名
print "Well done! You are a polite coder!" # 如无异常,输出祝贺消息
return super(CleanerMeta, cls).__new__(cls, class_name, bases, attrs)
# 重要!这行一定不能漏!!这回调用内建的类构造器来构造类,否则定义好的类将会变成 None
现在,只需这样定义基类:
class APIBase(object):
__metaclass__ = CleanerMeta
# ...
那么所有 APIBase 的派生类都会接受安全审查(奸笑~~):
class ImAGoodBoy(APIBase):
a_polite_attribute = 1
# [Output] Well done! You are a polite coder!
class FuckMyBoss(APIBase):
pass
# [Output] NameError: Sensitive words "fuck" detected in the string "FuckMyBoss".
class PretendToBePolite(APIBase):
def __fuck_your_asshole(self):
pass
# [Output] NameError: Sensitive words "asshole", "fuck" detected in the string "_PretendToBePolite__fuck_your_asshole".
看,即使像最后一个例子中的私有属性也难逃审查,因为它们本质都是相同的。
甚至,你还可以对有问题的属性进行偷偷的修改,比如 让不文明的函数在调用时打出一行警告 等等,这里就不多说了。
元类 在实际开发中的应用
日常开发时,元类 常用吗?
当然,Django 的 ORM 就是一个例子,大名鼎鼎的 SQLAlchemy 也用了这种黑魔法。
此外,在一些小型的库中,也有 元类 的身影。比如 abc(奇怪的名字~~)——这是 python 的一个内建库,用于模拟 抽象基类(Abstract Base Classes)。开发者可以使用 abc.abstractmethod 装饰器,将 指定了 __metaclass__ = abc.ABCMeta 的类的方法定义成 抽象方法,同时这个类也成了 抽象基类,抽象基类是不可实例化的。这便实现了对 抽象基类 的模拟。
倘若你也有需要动态修改类定义的需求,不妨也试试这种“黑魔法”。
小结
类 也是 对象,所有的类都是type的实例
元类(Meta Classes)是类的类
__metaclass__ = Meta 是 Meta(name, bases, dict) 的 语法糖
可以通过重载元类的 __new__ 方法,修改 类定义 的行为
本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉
本文系统来源:php中文网