目次
ディレクトリ
1. tarnado の紹介
IIの公式説明です
3. テストプログラム
IV. アプリケーションクラスの分析
1.アプリケーションの初期化プロセス
コード 1
1 まだ理解できていないので、後ほど追加します。
<1> 主に、上記のuiモジュールとメソッドの違いは何でしょうか?デフォルトで与えられるシステムモジュールとメソッド。
  代码四
  代码五
  代码六  
  代码七
  代码八
   代码九 

tarnadoの紹介と使用例

Jun 30, 2017 pm 02:26 PM
ソースコード シリーズ

ディレクトリ

  • tarnado

  • tarnadoソースコードのインストール

  • tarnadoテストプログラム

  • アプリケーションクラス分析

1. tarnado の紹介

最近 Python を勉強していて、偶然 tarnado に出会ったのですが、tarnado とは何でしょうか? tarnado は Python で開発されたノンブロッキング Web サーバー フレームワークであり、多くの主流 Web フレームワークとは大きく異なります (もちろん、他の Web フレームワークについてはあまり知りません)。 1 秒あたりの接続数が多く、リアルタイム Web サービスに最適です。以下のアドレスがtarnado

IIの公式説明です

上記のアドレスにアクセスしてtornado-1.2.1.tar.gzをダウンロードしてください

解凍後、cmdコマンドボックスでこのパスを見つけてインストールしてください。具体的な手順は次のとおりです:

注: 私のテスト後、このコードは python3.5 では実行できませんが、2.7 では実行できるため、テストのために python2.7 にインストールすることをお勧めします。そして学ぶこと。

3. テストプログラム

インストールが完了したら、pycharmを開き、新しいpyファイルを作成し、次のテストコードを記述します。実行後、ブラウザにhttp://127.0.0.1:8888と入力してください。 , world という文字が表示され、インストールが成功したことを意味します。

 1 import tornado.ioloop 2 import tornado.web 3  4 class MainHandler(tornado.web.RequestHandler): 5     def get(self): 6         self.write("Hello, world") 7  8 application = tornado.web.Application([ 9     (r"/", MainHandler),10 ])11 12 if __name__ == "__main__":13     application.listen(8888)14     tornado.ioloop.IOLoop.instance().start()
ログイン後にコピー
テストコード

IV. アプリケーションクラスの分析

さて、いよいよアプリケーションの分析をしていきますが、その分析の前にテストコードの実行処理についてお話しましょう。

 1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # zhou 4 # 2017/6/27 5  6 # 导入两个模块 7 import tornado.ioloop 8 import tornado.web 9 10 # 1. 把类RequestHandler载入到内存中11 # 2. 把类RequestHandler做为参数传入MainHandler中12 # 3. 把类MainHandler载入到内存中13 # 以上三个步骤实质上都不会坐任何操作,仅仅只是把类装载到内存中以便后续调用14 class MainHandler(tornado.web.RequestHandler):15     def get(self):16         self.write("Hello, world")17 18 19 # 丛这一步骤开始才开始真正的创建对象20 # 1. 类Application创建了一个对象,名称为application21 # 2. r"/" 这个是正则表达式类型的/,也就是我们在浏览器中输入的url22 # 3. 把类MainHandler作为参数传递到application中23 # 4. 这里面传递的仅仅只是一个变量[]24 application = tornado.web.Application([25     (r"/", MainHandler),26 ])27 28 if __name__ == "__main__":29     30     # 调用application对象中的listen方法,把8888作为端口号传递进去31     application.listen(8888)32     tornado.ioloop.IOLoop.instance().start()
ログイン後にコピー
テストプログラムの実行プロセスの紹介

最初に分析するのは次のコード行です

application =
ログイン後にコピー
A collection of request handlers that make up a web application.把许多请求处理器组合起来以实现web应用
ログイン後にコピー
<br>
ログイン後にコピー

1.アプリケーションの初期化プロセス

 1 def __init__(self, handlers=None, default_host="", transforms=None, 2              wsgi=False, **settings): 3     if transforms is None: 4         self.transforms = [] 5         if settings.get("gzip"): 6             self.transforms.append(GZipContentEncoding) 7         self.transforms.append(ChunkedTransferEncoding) 8     else: 9         self.transforms = transforms10     self.handlers = []11     self.named_handlers = {}12     self.default_host = default_host13     self.settings = settings14     self.ui_modules = {}15     self.ui_methods = {}16     self._wsgi = wsgi17     self._load_ui_modules(settings.get("ui_modules", {}))18     self._load_ui_methods(settings.get("ui_methods", {}))19     if self.settings.get("static_path"):20         path = self.settings["static_path"]21         handlers = list(handlers or [])22         static_url_prefix = settings.get("static_url_prefix",23                                          "/static/")24         handlers = [25                        (re.escape(static_url_prefix) + r"(.*)", StaticFileHandler,26                         dict(path=path)),27                        (r"/(favicon\.ico)", StaticFileHandler, dict(path=path)),28                        (r"/(robots\.txt)", StaticFileHandler, dict(path=path)),29                    ] + handlers30     if handlers: self.add_handlers(".*$", handlers)31 32     # Automatically reload modified modules33     if self.settings.get("debug") and not wsgi:34         import autoreload35         autoreload.start()
ログイン後にコピー
初期化コード

コード 1

。オブジェクト アプリケーションの変換変数をカプセル化します。ユーザーが変数を指定しない場合、システムはデフォルトでサーバーとクライアント間の送信プロセスを実行します。ある程度圧縮して逐一送信する必要があります

###################################################if transforms is None:
    self.transforms = []if settings.get("gzip"):
        self.transforms.append(GZipContentEncoding)
    self.transforms.append(ChunkedTransferEncoding)else:
    self.transforms = transforms###################################################这里面主要包含了三个类:
    GZipContentEncoding(OutputTransform)        # gzip内容编码ChunkedTransferEncoding(OutputTransform)    # 分块传输编码OutputTransform()                           # 是上面两个类的父类        解释:A transform modifies the result of an HTTP request(e.g., GZip encoding)
        主要是用来对一个http请求的结果进行转换的,可以是gzip压缩
ログイン後にコピー

コード2

1 まだ理解できていないので、後ほど追加します。

self.handlers = []
self.named_handlers = {}
self.default_host = default_host
self.settings = settings
self.ui_modules = {}
self.ui_methods = {}
self._wsgi = wsgi
ログイン後にコピー

コード3

<1> 主に、上記のuiモジュールとメソッドの違いは何でしょうか?デフォルトで与えられるシステムモジュールとメソッド。

りー

  他主要调用了两个方法,在此仅仅对第一个方法进行简单的描述(_load_ui_modules)

  因为第二个方法和这个modules是一样的

 1 def _load_ui_modules(self, modules): 2     if type(modules) is types.ModuleType: 3         self._load_ui_modules(dict((n, getattr(modules, n)) 4                                    for n in dir(modules))) 5     elif isinstance(modules, list): 6         for m in modules: self._load_ui_modules(m) 7     else: 8         assert isinstance(modules, dict) 9         for name, cls in modules.iteritems():10             try:11                 if issubclass(cls, UIModule):12                     self.ui_modules[name] = cls13             except TypeError:14                 pass
ログイン後にコピー
_load_ui_modules源代码

  对于上面源代码解析

# 把传入的模块modules全部变成字典的形式封装到ui_modules变量中def _load_ui_modules(self, modules):# types是一个.py文件,他主要是为了定义一些简单的函数,类似于内置函数可以直接拿来使用的# types里面关于ModuleType的描述是:ModuleType = type(sys) 也就是sys的类型<type &#39;module&#39;># 这里其实就是为了判断传出的modules是不是一个模块的类型,如果是就把它变成一个字典形式递归判断if type(modules) is types.ModuleType:
        self._load_ui_modules(dict((n, getattr(modules, n))                                   for n in dir(modules)))#判断modules是不是一个列表,如果是列表,就把列表里面的元素重新代入方法中进行调用                             elif isinstance(modules, list):for m in modules: self._load_ui_modules(m)else:# 此处是一个断言机制,也就是说已经肯定了modules一定是一个字典形式的样子assert isinstance(modules, dict)# 因为modules是一个字典,所以就把键和值分别赋值给name和cls,然后判断每一个键的值cls是不是UIModule的一个子类,如果是# 就把这个值添加到前面封装的一个变量中self.ui_modules[name] = clsfor name, cls in modules.iteritems():try:if issubclass(cls, UIModule):
                    self.ui_modules[name] = clsexcept TypeError:pass
ログイン後にコピー

 

  代码四

   <1>. 它定义了一系列的变量,最重要的变量是handler,  其中又引出了一个类StaticFileHandler而这个类又是继承了RequestHandler,因为此处并没有创建任何关于这个类的对象,所以此处不再深究等真正调用时候在来关注。

   但是从条件语句中,我们就可以看出来,当setting中不含static的时候,并不会去创建这些变量,这一点是要注意的。

# 定义了一系列的变量如handlers,path,static_url_prefix   # 当settings中包含了static_path这个键的时候,才会去定义这些变量         if self.settings.get("static_path"):
    path = self.settings["static_path"]
    handlers = list(handlers or [])
    static_url_prefix = settings.get("static_url_prefix",                                     "/static/")
    handlers = [
        (re.escape(static_url_prefix) + r"(.*)", StaticFileHandler,
         dict(path=path)),
        (r"/(favicon\.ico)", StaticFileHandler, dict(path=path)),
        (r"/(robots\.txt)", StaticFileHandler, dict(path=path)),
    ] + handlers
ログイン後にコピー

 

  代码五

    <1>. 添加给定的处理器到系统的处理器列表中。(其实这样说可能不太准确, 因为我们从代码四就可以看出来,如果我们给定的url包含了static_path,那么给定的处理器无论如何都会发生改变)

if handlers: self.add_handlers(".*$", handlers)
ログイン後にコピー

  代码六  

    add_handles函数的解析

def add_handlers(self, host_pattern, host_handlers):# 添加给定的处理器到系统的处理器列表中,注意主机模式是按顺序进行处理的,直到第一个被匹配到的这就意味着所有给定主机的处理器必须被添加到处理器中"""Appends the given handlers to our handler list.

    Note that host patterns are processed sequentially in the
    order they were added, and only the first matching pattern is
    used.  This means that all handlers for a given host must be
    added in a single add_handlers call."""# 如果给定主机模式不是以"$"结尾的,就添加$到结尾if not host_pattern.endswith("$"):
        host_pattern += "$"handlers = []# The handlers with the wildcard host_pattern are a special# case - they're added in the constructor but should have lower# precedence than the more-precise handlers added later.# If a wildcard handler group exists, it should always be last# in the list, so insert new groups just before it.# 带有通配符的handlers是一个特殊情况,他们本来在构造方法就已经被添加了,但是他们的优先级却低于一些重要的处理器,因此应该在之后被添加# 所以如果带有通配符的处理器组存在,就应该把他们放在一个列表的最后面,否则就插在他的前面# 下面这段代码就是这个意思,如果他的pattern是'.*$'开头的,代表他是没有通配符的,所以就把他插入最后一个的前面,否则有通配符的就直接添加到后面if self.handlers and self.handlers[-1][0].pattern == '.*$':
        self.handlers.insert(-1, (re.compile(host_pattern), handlers))else:
        self.handlers.append((re.compile(host_pattern), handlers))# 这个是对我们传入的host_handlers进行一个解析,把第一个采纳数给pattern,第二个给handler如果有三个,就赋值给kwargs如果没有第三个kwargs=={}for spec in host_handlers:if type(spec) is type(()):assert len(spec) in (2, 3)
            pattern = spec[0]
            handler = spec[1]if len(spec) == 3:
                kwargs = spec[2]else:
                kwargs = {}# 赋值完成之后就把这些参数封装到类URLSpec中spec = URLSpec(pattern, handler, kwargs)# 类URLSpec创建了对象spec之后,会重新给self.named_handlers添加一个handlers的键值对,如果键值本身就存在,就会往日志里面写入警告信息        handlers.append(spec)if spec.name:if spec.name in self.named_handlers:
                logging.warning("Multiple handlers named %s; replacing previous value",
                    spec.name)
            self.named_handlers[spec.name] = spec
ログイン後にコピー

 

  

  代码七

  类URLSpec的解析

  在代码六中创建了一个spec对象,用的类URLSpec创建的

class URLSpec(object):# 这个类的作用主要是在url和handlers之间做一个特定的映射,主要的体现应该就是前面的变量name_handlers# 前面的赋值语句:self.named_handlers[spec.name] = spec"""Specifies mappings between URLs and handlers."""def __init__(self, pattern, handler_class, kwargs={}, name=None):"""Creates a URLSpec.

        Parameters:
        # 传递进来得主机模式
        pattern: Regular expression to be matched.  Any groups in the regex
            will be passed in to the handler's get/post/etc methods as
            arguments.
            
        # 这个不是特别懂,但是意思是RequestHandler的子类将被调用
        handler_class: RequestHandler subclass to be invoked.
        kwargs (optional): A dictionary of additional arguments to be passed
            to the handler's constructor.
            
        # 这个handler的名字,是一个额外的参数
        name (optional): A name for this handler.  Used by
            Application.reverse_url."""if not pattern.endswith('$'):
            pattern += '$'self.regex = re.compile(pattern)
        self.handler_class = handler_class
        self.kwargs = kwargs
        self.name = name
        self._path, self._group_count = self._find_groups()
ログイン後にコピー

  代码八

  方法self._find_groups() 

  这个方法比较有意思,后面会带一个例子来解释一下

def _find_groups(self):# 就是给特定的url返回一个元组,下面的就是例子,括号里面的内容都会转换成%s,后面的2代表小括号括号的个数"""Returns a tuple (reverse string, group count) for a url.

    For example: Given the url pattern /([0-9]{4})/([a-z-]+)/, this method
    would return ('/%s/%s/', 2)."""# 得到pattern的字符串形式,去掉开头的^和结尾的$符号pattern = self.regex.patternif pattern.startswith('^'):
        pattern = pattern[1:]if pattern.endswith('$'):
        pattern = pattern[:-1]# 如果正常情况下regex.groups的值应该是等于count的,除非特别复杂的url,会返回两个noneif self.regex.groups != pattern.count('('):# The pattern is too complicated for our simplistic matching,# so we can't support reversing it.return (None, None)        # 这个就是把url转换成元组的具体代码,代码实现的是把括号里面的内容全部转换成%spieces = []for fragment in pattern.split('('):if ')' in fragment:
            paren_loc = fragment.index(')')if paren_loc >= 0:
                pieces.append('%s' + fragment[paren_loc + 1:])else:
            pieces.append(fragment)    # 把picese重新拼接成字符,返回回去return (''.join(pieces), self.regex.groups)
ログイン後にコピー
import re

pattern = "/abcd123([0-9]{4})/lwjeg([a-z-]+)/"regex = re.compile(pattern)
pieces = []print(pattern.split('('))for fragment in pattern.split('('):if ')' in fragment:# 找到‘)’的位置paren_loc = fragment.index(')')if paren_loc >= 0:# 把')'之后的所有内容拼接起来pieces.append('%s' + fragment[paren_loc + 1:])else:
        pieces.append(fragment)print(pieces)

结果:
['/abcd123', '[0-9]{4})/lwjeg', '[a-z-]+)/']
['/abcd123', '%s/lwjeg', '%s/']
ログイン後にコピー

   代码九 

# 自动的去重载改变的模块,这个调用的是autorelaad模块实现的    # Automatically reload modified modulesif self.settings.get("debug") and not wsgi:import autoreload
    autoreload.start()
ログイン後にコピー

  至此 

application = tornado.web.Application([<br>    (r"/", MainHandler),<br>])
ログイン後にコピー

以上がtarnadoの紹介と使用例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

ソフトウェアソースコード保護におけるPythonの応用実践 ソフトウェアソースコード保護におけるPythonの応用実践 Jun 29, 2023 am 11:20 AM

Python 言語は高級プログラミング言語として、学習が容易で読み書きも容易であり、ソフトウェア開発の分野で広く使用されています。ただし、Python のオープン ソースの性質により、ソース コードには他の人が簡単にアクセスできるため、ソフトウェアのソース コードの保護にいくつかの課題が生じます。したがって、実際のアプリケーションでは、Python ソース コードを保護し、そのセキュリティを確保するために何らかの方法を講じる必要があることがよくあります。ソフトウェア ソース コードの保護では、Python のさまざまなアプリケーション プラクティスから選択できます。以下は一般的なものです

Xiaomi 15シリーズの完全なコードネームが明らかに:Dada、Haotian、Xuanyuan Xiaomi 15シリーズの完全なコードネームが明らかに:Dada、Haotian、Xuanyuan Aug 22, 2024 pm 06:47 PM

Xiaomi Mi 15シリーズは10月に正式リリースされる予定で、その全シリーズのコードネームが海外メディアのMiCodeコードベースで公開されている。その中でもフラッグシップモデルであるXiaomi Mi 15 Ultraのコードネームは「Xuanyuan」(「玄源」の意味)です。この名前は中国神話に登場する高貴さを象徴する黄帝に由来しています。 Xiaomi 15のコードネームは「Dada」、Xiaomi 15Proのコード名は「Haotian」(「好天」の意味)です。 Xiaomi Mi 15S Proの内部コード名は「dijun」で、「山と海の古典」の創造神である淳皇帝を暗示しています。 Xiaomi 15Ultra シリーズのカバー

Huawei Mate 60シリーズ、新しいAI排除+イメージアップグレード、秋のプロモーションを楽しむのに最適な時期 Huawei Mate 60シリーズ、新しいAI排除+イメージアップグレード、秋のプロモーションを楽しむのに最適な時期 Aug 29, 2024 pm 03:33 PM

昨年Huawei Mate60シリーズが発売されて以来、個人的にはMate60Proをメインで使っています。ほぼ1年の間に、Huawei Mate60Proは複数のOTAアップグレードを受け、全体的なエクスペリエンスが大幅に向上し、人々に常に新しい感覚を与えました。たとえば、最近、Huawei Mate60 シリーズは再びイメージング機能の大幅なアップグレードを受けました。 1 つ目は、新しい AI 除去機能で、通行人やゴミをインテリジェントに除去し、空白領域を自動的に埋めることができます。2 つ目は、メインカメラの色の精度と望遠の鮮明さが大幅に向上しました。新学期シーズンであることを考慮して、Huawei Mate60シリーズは秋のプロモーションも開始しました。携帯電話の購入時に最大800元の割引が受けられ、開始価格は4,999元という低価格です。よく使われる、価値の高い新製品が多い

idea で Tomcat のソースコードを表示する方法 idea で Tomcat のソースコードを表示する方法 Jan 25, 2024 pm 02:01 PM

IDEA で Tomcat ソース コードを表示する手順: 1. Tomcat ソース コードをダウンロードする; 2. Tomcat ソース コードを IDEA にインポートする; 3. Tomcat ソース コードを表示する; 4. Tomcat の動作原理を理解する; 5. 注意事項; 6. 継続的な学習と更新する; 7. ツールとプラグインを使用する; 8. コミュニティに参加して貢献する。詳細な紹介: 1. Tomcat ソース コードをダウンロードします。ソース コード パッケージは、Apache Tomcat の公式 Web サイトからダウンロードできます。通常、これらのソース コード パッケージは ZIP または TAR 形式などです。

iPhone 15 と iPhone 15 Pro のどちらを選択すればよいですか? 9つの大きな違いを一度に iPhone 15 と iPhone 15 Pro のどちらを選択すればよいですか? 9つの大きな違いを一度に Sep 14, 2023 am 08:01 AM

本日、iPhone15とiPhone15Proが正式に発売されましたが、Proシリーズはハイエンドモデルとして価格が高いだけでなく、独自の機能も多く搭載されており、購入後に問題が発生しないように、消費者は購入前に違いを認識する必要があります。 iPhone15. Proシリーズのみの機能です。これらのモニターには同じ表示パネルが装備されていますが、ProMotion 自動適応更新頻度テクノロジーと常時表示機能は、依然として Pro シリーズ専用です。残りのiPhone 15およびiPhone 15 Proシリーズは、解像度、コントラスト、ピーク輝度などの点で同じです。アクションボタン アクションボタンは現在、iPhone 15 Pro シリーズ専用のデザインとなっており、ユーザーがカスタマイズできます。

PHPコードのソースコードを解釈・実行せずにブラウザに表示するにはどうすればよいでしょうか? PHPコードのソースコードを解釈・実行せずにブラウザに表示するにはどうすればよいでしょうか? Mar 11, 2024 am 10:54 AM

PHPコードのソースコードを解釈・実行せずにブラウザ上に表示するにはどうすればよいでしょうか? PHP は、動的 Web ページの開発に一般的に使用されるサーバー側スクリプト言語です。サーバー上で PHP ファイルが要求されると、サーバーはそのファイル内の PHP コードを解釈して実行し、最終的な HTML コンテンツを表示のためにブラウザーに送信します。ただし、PHP ファイルのソース コードを実行するのではなく、ブラウザーに直接表示したい場合があります。この記事では、PHPコードのソースコードを解釈・実行せずにブラウザ上に表示する方法を紹介します。 PHPでは、次のように使用できます

ソースコードをオンラインで閲覧できる Web サイト ソースコードをオンラインで閲覧できる Web サイト Jan 10, 2024 pm 03:31 PM

ブラウザの開発者ツールを使用して、Web サイトのソース コードを表示できます。Google Chrome ブラウザの場合: 1. Chrome ブラウザを開き、ソース コードを表示する Web サイトにアクセスします。2. Web 上の任意の場所を右クリックします。ページに移動して「検査」を選択するか、ショートカット キー Ctrl + Shift + I を押して開発者ツールを開きます; 3. 開発者ツールの上部メニュー バーで、「要素」タブを選択します; 4. HTML と CSS コードを確認するだけですウェブサイトの。

vueでソースコードを表示できるのでしょうか? vueでソースコードを表示できるのでしょうか? Jan 05, 2023 pm 03:17 PM

Vue ではソースコードを表示できます Vue でソースコードを表示する方法は、 1. 「git clone https://github.com/vuejs/vue.git」で Vue を入手する; 2. 「npm i」で依存関係をインストールする; 3. 「 npm i -g rollup」を使用してロールアップをインストールします; 4. 開発スクリプトを変更します; 5. ソース コードをデバッグします。

See all articles