对峰值规则的扩展,用于对方法进行优先级排序,以避免方法不明确的情况
prioritized_methods的Python项目详细描述
本模块提供四个装饰器:
^{tt1}$
^{tt2}$
^{tt3}$
^{tt4}$
除了接受 可选的prio参数,可用于提供可比较的对象 (通常是整数)用来消除歧义的 超过规则适用于给定参数而没有规则的情况 比另一个更具体。也就是说,在这种情况下 peak.rules.AmbiguousMethods本应筹集。
这对于希望通过泛型函数进行扩展的库很有用 但是希望他们的用户可以轻松地重写一个方法,而不需要知道如何 写一个更具体的规则或当它不可行时。
例如,turbojson提供了一个jsonify函数,其外观如下:
>>> def jsonify(obj): ... "jsonify an object"
并对其进行扩展,以便能够以某种方式处理sqlalchemy映射类 与此类似:
>>> from peak.rules import when >>> def jsonify_sa(obj): ... print "You're a SA object and I'm going to jsonify you!" >>> when(jsonify, "hasattr(obj, 'c')")(jsonify_sa) # doctest: +ELLIPSIS <function jsonify_sa at ...> >>> class Person(object): ... def __init__(self): ... self.c = "im a stub" >>> jsonify(Person()) You're a SA object and I'm going to jsonify you!
不过,到目前为止,当库的用户想要覆盖 在实现过程中,由于他们必须编写一个 可能很乏味的特定规则,例如:
hasattr(self, 'c') and isinstance(obj, Person)
注意hasattr测试,即使isinstance(obj, Person)暗示它, 只是为了使它比内置的更具体,这会使 表达变得更加复杂。
否则就会发生这种情况:
>>> def jsonify_Person(obj): ... print "No way, I'm going to jsonify you!" >>> when(jsonify, (Person,))(jsonify_Person) # doctest: +ELLIPSIS <function jsonify_Person at ...> >>> try: ... jsonify(Person()) ... except AmbiguousMethods: ... print "I told you, gfs can sometimes be a pain" I told you, gfs can sometimes be a pain
要纠正这种情况,prioritized_when可以用来提供 将重写用when:
声明的实现>>> def jsonify_Person2(obj): ... print "No way, I'm going to jsonify you!" >>> prioritized_when(jsonify, (Person,))(jsonify_Person2) # doctest: +ELLIPSIS <function jsonify_Person2 at ...> >>> jsonify(Person()) No way, I'm going to jsonify you!
注意,我们不需要prio参数。这是因为方法 用prioritized_when修饰的始终覆盖那些 用peak.rules.when装饰。
用prioritized_when修饰的方法也可以重写其他方法 已经由同一个decorator使用prio参数进行了修饰, 如果两者相等的话,比较更大的胜利的人 AmbiguousMethods将照常筹集。
>>> def jsonify_Person3(obj): ... print "Don't be so smart, I am, my prio is higher!">>> prioritized_when(jsonify, (Person,), prio=1)(jsonify_Person3) # doctest: +ELLIPSIS <function jsonify_Person3 at ...>>>> jsonify(Person()) Don't be so smart, I am, my prio is higher!
为了方便起见,还提供了一个genericdecorator,它的行为 像peak.rules.dispatch.generic除了when,…,``之后`` 将作为装饰函数的属性绑定的装饰器将 优先顺序:
>>> @generic ... def f(n): pass >>> f(5) Traceback (most recent call last): ... NoApplicableMethods: ((5,), {})
添加默认规则:
>>> @f.when() ... def default_f(n): ... return n >>> f(5) 5
添加覆盖前者的默认规则:
>>> @f.when(prio=1) ... def new_default_f(n): ... return n+1 >>> f(5) 6