突然脑洞了一下,想和大家讨论一下。python 的 decorater 和 elisp 的 advice 有可比性吗?谁更强大?
我看到 Python 装饰器也想到了「不就跟 Emacs Advice 的作用差不多吗!」,函数在 Python 和 Emacs Lisp 中都可以当作值来使用,Python 装饰器函数就是传入一个函数,返回一个函数,比如:
def uppercase(func):
def wrapper():
original_result = func()
modified_result = original_result.upper()
return modified_result
return wrapper
def hello():
return "Hello"
print(uppercase(hello)())
# => "HELLO"
等价的 Emacs Lisp 代码:
(defun hello ()
'"Hello")
(defun uppercase (func)
(lambda ()
(upcase (funcall func))))
(funcall (uppercase #'hello))
;; => "HELLO"
Python 还提供了一种特殊语法 @
来使用装饰器:
@uppercase
def hello2():
return "Hello"
print(hello2())
# => "HELLO"
Emacs 没加额外的语法,advice-add
是一个普通函数:
(advice-add 'hello :around #'uppercase)
(funcall (hello))
;; => "HELLO"
当然我还没有了解过 Emacs Advice 是如何工作的,以上是我目前的认识。
1 个赞
add-function和add-advice的区别又是什么?为什么add-function看起来还能修饰一个变量?
因为add-function接受一个广义变量作为参数,修饰目标广义变量处的函数或macro
1 个赞
当然不一样,一个是主动调用一个是被动调用,我倒觉得add-advice和java的aop很像。
1 个赞
就是aop, 不过aop不是java 独有的 https://en.wikipedia.org/wiki/Aspect-oriented_programming#cite_note-29 虽然这个链接的内容似乎不存在了…(还可以看archived)
1 个赞
从 advice--make-1
可以看出,advice 会在原来的函数前面插入一段代码:
(defun advice--make-1 (byte-code stack-depth function main props)
"Build a function value that adds FUNCTION to MAIN."
(let ((adv-sig (gethash main advertised-signature-table))
(advice
(apply #'make-byte-code 128 byte-code
(vector #'apply function main props) stack-depth nil
(and (or (commandp function) (commandp main))
(list (advice--make-interactive-form
function main))))))
(when adv-sig (puthash advice adv-sig advertised-signature-table))
advice))
把原函数做为 advice 函数的参数:
(with-emacs "~/.local/bin/emacs"
(byte-compile (defun foo () (message "foo"))))
;; => "#[nil \"ÀÁ!\" [message \"foo\"] 2]"
(with-emacs "~/.local/bin/emacs"
(defun foo () (message "foo"))
(defun foo@before () (message "foo-before"))
(advice-add 'foo :before 'foo@before)
(byte-compile 'foo))
;; => "#[128 \"ÀÁ\\\"ÀÂ\\\"\" [apply foo@before (lambda nil (message \"foo\")) nil] 4 nil]"
1 个赞
:after 会在后面
:around 会将原函数作为一个参数
M-x disassemble 可以查看汇编代码
Python 的 Wiki 上声称 decorator 就是 decorator pattern,而 decorator pattern 就是一种 AOP
1 个赞