summaryrefslogtreecommitdiff
path: root/docs/_locale/zh_CN/LC_MESSAGES/plugindev.po
blob: 15da64b8b1bb74d269c7d04acaa140a699335ae3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2009-2020, Marcel Hellkamp
# This file is distributed under the same license as the Bottle package.
# 
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: bottle\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-31 18:35+0100\n"
"PO-Revision-Date: 2020-12-31 17:35+0000\n"
"Last-Translator: defnull <marc@gsites.de>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/bottle/bottle/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#: ../../plugindev.rst:6
msgid "Plugin Development Guide"
msgstr "插件开发指南"

#: ../../plugindev.rst:8
msgid ""
"This guide explains the plugin API and how to write custom plugins. I "
"suggest reading :ref:`plugins` first if you have not done that already. You "
"might also want to have a look at the :doc:`/plugins/index` for some "
"practical examples."
msgstr "这份指南介绍了插件的API,以及如何编写自己的插件。我建议先阅读 :ref:`plugins` 这一部分,再看这份指南。 :doc:`/plugins/index` 这里也有一些实际的例子。"

#: ../../plugindev.rst:12
msgid ""
"This is a draft. If you see any errors or find that a specific part is not "
"explained clear enough, please tell the `mailing-list "
"<mailto:bottlepy@googlegroups.com>`_ or file a `bug report "
"<https://github.com/bottlepy/bottle/issues>`_."
msgstr "这是一份初稿。如果你发现了任何错误,或某些部分解释的不够清楚,请通过 `邮件列表 <mailto:bottlepy@googlegroups.com>`_ 或  `bug report <https://github.com/bottlepy/bottle/issues>`_ 告知。"

#: ../../plugindev.rst:16
msgid "How Plugins Work: The Basics"
msgstr "插件工作方式:基础知识"

#: ../../plugindev.rst:18
msgid ""
"The plugin API builds on the concept of `decorators "
"<http://docs.python.org/glossary.html#term-decorator>`_. To put it briefly, "
"a plugin is a decorator applied to every single route callback of an "
"application."
msgstr "插件的API是通过Python的 `修饰器 <http://docs.python.org/glossary.html#term-decorator>`_ 来实现的。简单来说,一个插件就是应用在route回调函数上的修饰器。"

#: ../../plugindev.rst:20
msgid ""
"This is just a simplification. Plugins can do a lot more than just "
"decorating route callbacks, but it is a good starting point. Lets have a "
"look at some code::"
msgstr ""

#: ../../plugindev.rst:36
msgid ""
"This plugin measures the execution time for each request and adds an "
"appropriate ``X-Exec-Time`` header to the response. As you can see, the "
"plugin returns a wrapper and the wrapper calls the original callback "
"recursively. This is how decorators usually work."
msgstr "这个插件计算每次请求的响应时间,并在响应头中添加了 ``X-Exec-Time`` 字段。如你所见,插件返回了一个wrapper函数,由它来调用原先的回调函数。这就是修饰器的常见工作方式了。"

#: ../../plugindev.rst:38
msgid ""
"The last line tells Bottle to install the plugin to the default application."
" This causes the plugin to be automatically applied to all routes of that "
"application. In other words, ``stopwatch()`` is called once for each route "
"callback and the return value is used as a replacement for the original "
"callback."
msgstr "最后一行,将该插件安装到Bottle的默认应用里面。这样,应用中的所有route都会应用这个插件了。就是说,每次请求都会调用 ``stopwatch()`` ,更改了route的默认行为。"

#: ../../plugindev.rst:40
msgid ""
"Plugins are applied on demand, that is, as soon as a route is requested for "
"the first time. For this to work properly in multi-threaded environments, "
"the plugin should be thread-safe. This is not a problem most of the time, "
"but keep it in mind."
msgstr "插件是按需加载的,就是在route第一次被访问的时候加载。为了在多线程环境下工作,插件应该是线程安全的。在大多数情况下,这都不是一个问题,但务必提高警惕。"

#: ../../plugindev.rst:42
msgid ""
"Once all plugins are applied to a route, the wrapped callback is cached and "
"subsequent requests are handled by the cached version directly. This means "
"that a plugin is usually applied only once to a specific route. That cache, "
"however, is cleared every time the list of installed plugins changes. Your "
"plugin should be able to decorate the same route more than once."
msgstr "一旦route中使用了插件后,插件中的回调函数会被缓存起来,接下来都是直接使用缓存中的版本来响应请求。意味着每个route只会请求一次插件。在应用的插件列表变化的时候,这个缓存会被清空。你的插件应当可以多次修饰同一个route。"

#: ../../plugindev.rst:44
msgid ""
"The decorator API is quite limited, though. You don't know anything about "
"the route being decorated or the associated application object and have no "
"way to efficiently store data that is shared among all routes. But fear not!"
" Plugins are not limited to just decorator functions. Bottle accepts "
"anything as a plugin as long as it is callable or implements an extended "
"API. This API is described below and gives you a lot of control over the "
"whole process."
msgstr "这种修饰器般的API受到种种限制。你不知道route或相应的应用对象是如何被修饰的,也不知道如何有效地存储那些在route之间共享的数据。但别怕!插件不仅仅是修饰器函数。只要一个插件是callable的或实现了一个扩展的API(后面会讲到),Bottle都可接受。扩展的API给你更多的控制权。"

#: ../../plugindev.rst:48
msgid "Plugin API"
msgstr "插件API"

#: ../../plugindev.rst:50
msgid ""
":class:`Plugin` is not a real class (you cannot import it from "
":mod:`bottle`) but an interface that plugins are expected to implement. "
"Bottle accepts any object of any type as a plugin, as long as it conforms to"
" the following API."
msgstr "``Plugin`` 类不是一个真正的类(你不能从bottle中导入它),它只是一个插件需要实现的接口。只要一个对象实现了以下接口,Bottle就认可它作为一个插件。"

#: ../../plugindev.rst:54
msgid ""
"Plugins must be callable or implement :meth:`apply`. If :meth:`apply` is "
"defined, it is always preferred over calling the plugin directly. All other "
"methods and attributes are optional."
msgstr "插件应该是callable的,或实现了 :meth:`apply` 方法。如果定义了 :meth:`apply` 方法,那么会优先调用,而不是直接调用插件。其它的方法和属性都是可选的。"

#: ../../plugindev.rst:58
msgid ""
"Both :meth:`Bottle.uninstall` and the `skip` parameter of "
":meth:`Bottle.route()` accept a name string to refer to a plugin or plugin "
"type. This works only for plugins that have a name attribute."
msgstr ":meth:`Bottle.uninstall` 方法和 :meth:`Bottle.route()` 中的 `skip` 参数都接受一个与名字有关的字符串,对应插件或其类型。只有插件中有一个name属性的时候,这才会起作用。"

#: ../../plugindev.rst:62
msgid ""
"The Plugin API is still evolving. This integer attribute tells bottle which "
"version to use. If it is missing, bottle defaults to the first version. The "
"current version is ``2``. See :ref:`plugin-changelog` for details."
msgstr "插件的API还在逐步改进。这个整形数告诉Bottle使用哪个版本的插件。如果没有这个属性,Bottle默认使用第一个版本。当前版本是 ``2`` 。详见 :ref:`plugin-changelog` 。"

#: ../../plugindev.rst:66
msgid ""
"Called as soon as the plugin is installed to an application (see "
":meth:`Bottle.install`). The only parameter is the associated application "
"object."
msgstr "插件被安装的时候调用(见 :meth:`Bottle.install` )。唯一的参数是相应的应用对象。"

#: ../../plugindev.rst:70
msgid ""
"As long as :meth:`apply` is not defined, the plugin itself is used as a "
"decorator and applied directly to each route callback. The only parameter is"
" the callback to decorate. Whatever is returned by this method replaces the "
"original callback. If there is no need to wrap or replace a given callback, "
"just return the unmodified callback parameter."
msgstr "如果没有定义 :meth:`apply` 方法,插件本身会被直接当成一个修饰器使用(译者注:Python的Magic Method,调用一个类即是调用类的__call__函数),应用到各个route。唯一的参数就是其所修饰的函数。这个方法返回的东西会直接替换掉原先的回调函数。如果无需如此,则直接返回未修改过的回调函数即可。"

#: ../../plugindev.rst:74
msgid ""
"If defined, this method is used in favor of :meth:`__call__` to decorate "
"route callbacks. The additional `route` parameter is an instance of "
":class:`Route` and provides a lot of meta-information and context for that "
"route. See :ref:`route-context` for details."
msgstr "如果存在,会优先调用,而不调用 :meth:`__call__` 。额外的 `route` 参数是 :class:`Route` 类的一个实例,提供很多该route信息和上下文。详见 :ref:`route-context` 。"

#: ../../plugindev.rst:78
msgid ""
"Called immediately before the plugin is uninstalled or the application is "
"closed (see :meth:`Bottle.uninstall` or :meth:`Bottle.close`)."
msgstr "插件被卸载或应用关闭的时候被调用,详见 :meth:`Bottle.uninstall` 或 :meth:`Bottle.close` 。"

#: ../../plugindev.rst:81
msgid ""
"Both :meth:`Plugin.setup` and :meth:`Plugin.close` are *not* called for "
"plugins that are applied directly to a route via the :meth:`Bottle.route()` "
"decorator, but only for plugins installed to an application."
msgstr ":meth:`Plugin.setup` 方法和 :meth:`Plugin.close` 方法 *不* 会被调用,如果插件是通过 :meth:`Bottle.route` 方法来应用到route上面的,但会在安装插件的时候被调用。"

#: ../../plugindev.rst:87
msgid "Plugin API changes"
msgstr "插件API的改动"

#: ../../plugindev.rst:89
msgid ""
"The Plugin API is still evolving and changed with Bottle 0.10 to address "
"certain issues with the route context dictionary. To ensure backwards "
"compatibility with 0.9 Plugins, we added an optional :attr:`Plugin.api` "
"attribute to tell bottle which API to use. The API differences are "
"summarized here."
msgstr "插件的API还在不断改进中。在Bottle 0.10版本中的改动,定位了route上下文字典中已确定的问题。为了保持对0.9版本插件的兼容,我们添加了一个可选的 :attr:`Plugin.api` 属性,告诉Bottle使用哪个版本的API。API之间的不同点总结如下。"

#: ../../plugindev.rst:91
msgid "**Bottle 0.9 API 1** (:attr:`Plugin.api` not present)"
msgstr "**Bottle 0.9 API 1** (无 :attr:`Plugin.api` 属性)"

#: ../../plugindev.rst:93
msgid "Original Plugin API as described in the 0.9 docs."
msgstr ""

#: ../../plugindev.rst:95
msgid "**Bottle 0.10 API 2** (:attr:`Plugin.api` equals 2)"
msgstr "**Bottle 0.10 API 2** ( :attr:`Plugin.api` 属性为2)"

#: ../../plugindev.rst:97
msgid ""
"The `context` parameter of the :meth:`Plugin.apply` method is now an "
"instance of :class:`Route` instead of a context dictionary."
msgstr " :meth:`Plugin.apply` 方法中的 `context` 参数,现在是 :class:`Route` 类的一个实例,不再是一个上下文字典。"

#: ../../plugindev.rst:103
msgid "The Route Context"
msgstr "Route上下文"

#: ../../plugindev.rst:105
msgid ""
"The :class:`Route` instance passed to :meth:`Plugin.apply` provides detailed"
" informations about the associated route. The most important attributes are "
"summarized here:"
msgstr ":class:`Route` 的实例被传递给 :meth:`Plugin.apply` 函数,以提供更多该route的相关信息。最重要的属性总结如下。"

#: ../../plugindev.rst:108
msgid "Attribute"
msgstr "属性"

#: ../../plugindev.rst:108
msgid "Description"
msgstr "描述"

#: ../../plugindev.rst:110
msgid "app"
msgstr ""

#: ../../plugindev.rst:110
msgid "The application object this route is installed to."
msgstr "安装该route的应用对象"

#: ../../plugindev.rst:111
msgid "rule"
msgstr ""

#: ../../plugindev.rst:111
msgid "The rule string (e.g. ``/wiki/<page>``)."
msgstr ""

#: ../../plugindev.rst:112
msgid "method"
msgstr ""

#: ../../plugindev.rst:112
msgid "The HTTP method as a string (e.g. ``GET``)."
msgstr "HTTP方法的字符串(例如: ``GET``)"

#: ../../plugindev.rst:113
msgid "callback"
msgstr ""

#: ../../plugindev.rst:113
msgid ""
"The original callback with no plugins applied. Useful for introspection."
msgstr "未应用任何插件的原始回调函数,用于内省。"

#: ../../plugindev.rst:115
msgid "name"
msgstr ""

#: ../../plugindev.rst:115
msgid "The name of the route (if specified) or ``None``."
msgstr "route的名字,如未指定则为 ``None``"

#: ../../plugindev.rst:116
msgid "plugins"
msgstr ""

#: ../../plugindev.rst:116
msgid ""
"A list of route-specific plugins. These are applied in addition to "
"application-wide plugins. (see :meth:`Bottle.route`)."
msgstr "route安装的插件列表,除了整个应用范围内的插件,额外添加的(见 :meth:`Bottle.route` )"

#: ../../plugindev.rst:118
msgid "skiplist"
msgstr ""

#: ../../plugindev.rst:118
msgid ""
"A list of plugins to not apply to this route (again, see "
":meth:`Bottle.route`)."
msgstr "应用安装了,但该route没安装的插件列表(见 meth:`Bottle.route` )"

#: ../../plugindev.rst:120
msgid "config"
msgstr ""

#: ../../plugindev.rst:120
msgid ""
"Additional keyword arguments passed to the :meth:`Bottle.route` decorator "
"are stored in this dictionary. Used for route-specific configuration and "
"meta-data."
msgstr "传递给 :meth:`Bottle.route` 修饰器的额外参数,存在一个字典中,用于特定的设置和元数据"

#: ../../plugindev.rst:125
msgid ""
"For your plugin, :attr:`Route.config` is probably the most important "
"attribute. Keep in mind that this dictionary is local to the route, but "
"shared between all plugins. It is always a good idea to add a unique prefix "
"or, if your plugin needs a lot of configuration, store it in a separate "
"namespace within the `config` dictionary. This helps to avoid naming "
"collisions between plugins."
msgstr "对你的应用而言, :attr:`Route.config` 也许是最重要的属性了。记住,这个字典会在所有插件中共享,建议添加一个独一无二的前缀。如果你的插件需要很多设置,将其保存在 `config` 字典的一个独立的命名空间吧。防止插件之间的命名冲突。"

#: ../../plugindev.rst:129
msgid "Changing the :class:`Route` object"
msgstr "改变 :class:`Route` 对象"

#: ../../plugindev.rst:131
msgid ""
"While some :class:`Route` attributes are mutable, changes may have unwanted "
"effects on other plugins. It is most likely a bad idea to monkey-patch a "
"broken route instead of providing a helpful error message and let the user "
"fix the problem."
msgstr ":class:`Route` 的一些属性是不可变的,改动也许会影响到其它插件。坏主意就是,monkey-patch一个损坏的route,而不是提供有效的帮助信息来让用户修复问题。"

#: ../../plugindev.rst:133
msgid ""
"In some rare cases, however, it might be justifiable to break this rule. "
"After you made your changes to the :class:`Route` instance, raise "
":exc:`RouteReset` as an exception. This removes the current route from the "
"cache and causes all plugins to be re-applied. The router is not updated, "
"however. Changes to `rule` or `method` values have no effect on the router, "
"but only on plugins. This may change in the future, though."
msgstr "在极少情况下,破坏规则也许是恰当的。在你更改了 :class:`Route` 实例后,抛一个 :exc:`RouteReset` 异常。这会从缓存中删除当前的route,并重新应用所有插件。无论如何,router没有被更新。改变 `rule` 或 `method` 的值并不会影响到router,只会影响到插件。这个情况在将来也许会改变。"

#: ../../plugindev.rst:137
msgid "Runtime optimizations"
msgstr "运行时优化"

#: ../../plugindev.rst:139
msgid ""
"Once all plugins are applied to a route, the wrapped route callback is "
"cached to speed up subsequent requests. If the behavior of your plugin "
"depends on configuration, and you want to be able to change that "
"configuration at runtime, you need to read the configuration on each "
"request. Easy enough."
msgstr "插件应用到route以后,被插件封装起来的回调函数会被缓存,以加速后续的访问。如果你的插件的行为依赖一些设置,你需要在运行时更改这些设置,你需要在每次请求的时候读取设置信息。够简单了吧。"

#: ../../plugindev.rst:141
msgid ""
"For performance reasons, however, it might be worthwhile to choose a "
"different wrapper based on current needs, work with closures, or enable or "
"disable a plugin at runtime. Let's take the built-in HooksPlugin as an "
"example: If no hooks are installed, the plugin removes itself from all "
"affected routes and has virtually no overhead. As soon as you install the "
"first hook, the plugin activates itself and takes effect again."
msgstr ""

#: ../../plugindev.rst:143
msgid ""
"To achieve this, you need control over the callback cache: "
":meth:`Route.reset` clears the cache for a single route and "
":meth:`Bottle.reset` clears all caches for all routes of an application at "
"once. On the next request, all plugins are re-applied to the route as if it "
"were requested for the first time."
msgstr "为了达到这个目的,你需要控制回调函数的缓存: :meth:`Route.reset` 函数清空单一route的缓存, :meth:`Bottle.reset` 函数清空所有route的缓存。在下一次请求的时候,所有插件被重新应用到route上面,就像第一次请求时那样。"

#: ../../plugindev.rst:145
msgid ""
"Both methods won't affect the current request if called from within a route "
"callback, of cause. To force a restart of the current request, raise "
":exc:`RouteReset` as an exception."
msgstr "如果在route的回调函数里面调用,两种方法都不会影响当前的请求。当然,可以抛出一个 :exc:`RouteReset` 异常,来改变当前的请求。"

#: ../../plugindev.rst:149
msgid "Plugin Example: SQLitePlugin"
msgstr "插件例子: SQLitePlugin"

#: ../../plugindev.rst:151
msgid ""
"This plugin provides an sqlite3 database connection handle as an additional "
"keyword argument to wrapped callbacks, but only if the callback expects it. "
"If not, the route is ignored and no overhead is added. The wrapper does not "
"affect the return value, but handles plugin-related exceptions properly. "
":meth:`Plugin.setup` is used to inspect the application and search for "
"conflicting plugins."
msgstr "这个插件提供对sqlite3数据库的访问,如果route的回调函数提供了关键字参数(默认是\"db\"),则\"db\"可做为数据库连接,如果route的回调函数没有提供该参数,则忽略该route。wrapper不会影响返回值,但是会处理插件相关的异常。 :meth:`Plugin.setup` 方法用于检查应用,查找冲突的插件。"

#: ../../plugindev.rst:218
msgid ""
"This plugin is actually useful and very similar to the version bundled with "
"Bottle. Not bad for less than 60 lines of code, don't you think? Here is a "
"usage example::"
msgstr "这个插件十分有用,已经和Bottle提供的那个版本很类似了(译者注:=。= 一模一样)。只要60行代码,还不赖嘛!下面是一个使用例子。"

#: ../../plugindev.rst:239
msgid ""
"The first route needs a database connection and tells the plugin to create a"
" handle by requesting a ``db`` keyword argument. The second route does not "
"need a database and is therefore ignored by the plugin. The third route does"
" expect a 'db' keyword argument, but explicitly skips the sqlite plugin. "
"This way the argument is not overruled by the plugin and still contains the "
"value of the same-named url argument."
msgstr "第一个route提供了一个\"db\"参数,告诉插件它需要一个数据库连接。第二个route不需要一个数据库连接,所以会被插件忽略。第三个route确实有一个\"db\"参数,但显式的禁用了sqlite插件,这样,\"db\"参数不会被插件修改,还是包含URL传过来的那个值。"