如何使用装饰器(bottle.py)

The*_*rry 3 python bottle python-2.7

我正在尝试使用bottle.py来构建一些网页.似乎使用瓶子的一个主要部分是学习使用装饰器,但我已经阅读了python docs解释装饰器是什么,但我仍然不确定我理解它们.

文档说:

"Python装饰器是对Python语法的一种特定更改,它允许我们更方便地更改函数和方法(以及未来版本中可能的类)."

听起来你正在调用一个函数进行一些更改,但我不知道为什么你会这样做或如何阅读装饰器.

看一些瓶子代码:

if __name__ == '__main__':
    PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
    STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static').replace('\\', '/')
    HOST = os.environ.get('SERVER_HOST', 'localhost')
    try:
        PORT = int(os.environ.get('SERVER_PORT', '5555'))
    except ValueError:
        PORT = 5555

    @bottle.route('/static/<filepath:path>')
    def server_static(filepath):
        """Handler for static files, used with the development server.
        When running under a production server such as IIS or Apache,
        the server should be configured to serve the static files."""
        return bottle.static_file(filepath, root=STATIC_ROOT)

    # Starts a local test server.
    bottle.run(server='wsgiref', host=HOST, port=PORT)
Run Code Online (Sandbox Code Playgroud)

这条线做@bottle.route('/static/<filepath:path>')什么?

如果它是一个奇特的函数调用那么为什么这样做而不是只是调用函数?

谢谢你的帮助!:d

7st*_*tud 7

看看这段代码:

def my_decorator(func):
    return lambda: print("goodbye")

def greet():
    print('hello')

result = my_decorator(greet)
result()

--output:--
goodbye
Run Code Online (Sandbox Code Playgroud)

以下是完成同样事情的快捷方式:

def my_decorator(func):
    return lambda: print("goodbye")

@my_decorator
def greet():
    print('hello')

greet()

--output:--
goodbye
Run Code Online (Sandbox Code Playgroud)

@my_decorator语法如下功能下方,greet以及使此调用:

greet = my_decorator(greet)
Run Code Online (Sandbox Code Playgroud)

my_decorator()必须定义该函数,以便:

  1. 它需要一个函数作为参数.

  2. 返回一个函数.

Python装饰器是对Python语法的一种特定更改,它允许我们更方便地更改函数和方法(以及未来版本中可能的类).

好吧,那么让我们说你要添加到greet()函数的任何内容:

def my_decorator(func):  # func = greet

    def add_to_greet():
        func()   #<*********This is greet()
        print('world') #<***This is additional stuff.

    return add_to_greet

@my_decorator
def greet():
    print('hello')

greet()

--output:--
hello
world
Run Code Online (Sandbox Code Playgroud)

这条线做了什么 @bottle.route('/static/<filepath:path>')

好的,你准备好了吗?如果@some_name语法指定参数,例如:

 @wrapper('world')
 def do_stuff():
Run Code Online (Sandbox Code Playgroud)

第一个 python将执行以下调用:

 @wrapper('world')
 def do_stuff():
      ...

 #****HERE:
 decorator = wrapper('world')  #decorator is a newly created variable
Run Code Online (Sandbox Code Playgroud)

wrapper()函数必须定义为:

  1. 拿任何古老的论点,例如'世界'
  2. 返回一个函数:
    1. 将函数作为参数.
    2. 返回一个函数.

其次,python将执行调用:

 @wrapper('world')
 def do_stuff():
     ...

 decorator = wrapper('world') 
 #*****HERE:   
 do_stuff = decorator(do_stuff) 
Run Code Online (Sandbox Code Playgroud)

呼!这是一个例子:

def wrapper(extra_greeting):

    def my_decorator(func):

        def add_to_greet():
            func()
            print(extra_greeting)

        return add_to_greet

    return my_decorator


@wrapper('world')
def greet():
    print('hello')

greet()

--output:--
hello
world
Run Code Online (Sandbox Code Playgroud)

现在,让我们分析一下这个装饰器:

@bottle.route('/static/<filepath:path>')
def server_static(filepath):
Run Code Online (Sandbox Code Playgroud)
bottle  -- a module
route   -- a function(or other callable) defined in the bottle module
'/static/<filepath:path>'  -- a route
Run Code Online (Sandbox Code Playgroud)

所以瓶子模块可能如下所示:

#bottle.py

def route(your_route):  #your_route <= '/static/<filepath:path>'

    def my_decorator(func):  #The decorator syntax will cause python to call this function with server_static as the argument

        def do_stuff(filepath):
            func(filepath)  #Call the server_static() function with the part of the url that matched filepath

        return do_stuff  #This function will be called when your code calls server_static(...)

    return my_decorator
Run Code Online (Sandbox Code Playgroud)

如果它是一个奇特的函数调用那么为什么这样做而不是只是调用函数?

先进的东西.

评论: 也许您忘了解释路由装饰器的具体用途?


@route('/hello')
def hello():
    return "Hello World!"
Run Code Online (Sandbox Code Playgroud)

route()装饰器将一段代码绑定到URL路径.在这种情况下,我们将/ hello路径链接到hello()函数.这称为路径(因此是装饰者名称),是该框架最重要的概念.您可以根据需要定义任意数量的路径.每当浏览器请求URL时,都会调用相关的函数,并将返回值发送回浏览器.就这么简单.

http://bottlepy.org/docs/dev/tutorial.html

路径可以包括通配符:

最简单的通配符形式由尖括号括起来的名称组成(例如<name>)....每个通配符匹配一个或多个字符,但在第一个斜杠(/)处停止.规则/<action>/<item>匹配如下:

Path        Result
/save/123   {'action': 'save', 'item': '123'}
/save/123/  No Match
/save/      No Match
//123       No Match
Run Code Online (Sandbox Code Playgroud)

过滤器用于定义更具体的通配符,和/或在将URL的匹配部分传递给回调之前对其进行转换.过滤的通配符声明为<name:filter>


实现了以下标准过滤器:

:path以非贪婪的方式匹配包括斜杠字符在内的所有字符,并且可用于匹配多个路径段.

http://bottlepy.org/docs/dev/routing.html