亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Lunar, 一個(gè)Python網(wǎng)絡(luò)框架的實(shí)現(xiàn)

邱勇 / 1939人閱讀

摘要:核心的幾個(gè)組件模板引擎,框架,請(qǐng)求和應(yīng)答的處理還是有一些難度,但是經(jīng)過一步步的分析和編碼還是能夠完成功能。模板引擎模板引擎是另外一個(gè)比較大和的模塊。

前前后后,大概兩個(gè)月的時(shí)間,lunar這個(gè)項(xiàng)目終于達(dá)到了一個(gè)很高的完整度。

Lunar是一個(gè)Python語言的網(wǎng)絡(luò)框架,類似于Django,F(xiàn)lask,Tornado等當(dāng)下流行的web framework。最初有這個(gè)想法是在大二下學(xué)期,當(dāng)時(shí)接觸Python web編程有一段時(shí)間。最早接觸Python web編程或許是在大一下?自覺當(dāng)時(shí)編程還沒有入門,第一個(gè)接觸的web框架是Django,很龐大的框架,當(dāng)時(shí)很low逼的去看那本Django Book的中文譯本,翻譯的其實(shí)很不錯(cuò)了,只是進(jìn)度會(huì)落后于當(dāng)前的版本,所以在跑example的時(shí)候會(huì)有一些問題,Django的龐大規(guī)模給我留下了很大的心理陰影,所以在之后,對(duì)于涉世未深的Pythoner,我可能都不會(huì)推薦Django作為第一個(gè)Python的網(wǎng)絡(luò)框架來學(xué)習(xí)。

整個(gè)框架的挑戰(zhàn)還是非常大的。核心的幾個(gè)組件(模板引擎,ORM框架,請(qǐng)求和應(yīng)答的處理)還是有一些難度,但是經(jīng)過一步步的分析和編碼還是能夠完成功能。項(xiàng)目受Flask非常大的影響,最初作為造輪子的初衷,幾乎完整的使用了Flask和SQLAlchemy的API接口。

項(xiàng)目同樣開源在Github上: https://github.com/jasonlvhit/lunar

也可以通過pip直接安裝:

$ pip install lunar

這里我大概的記述一下lunar整個(gè)項(xiàng)目的各個(gè)組件的設(shè)計(jì)和實(shí)現(xiàn)。

ORM framework

首先是ORM。

python圈子里面還是有很多很著名的orm框架,SQLAlchemy,peewee, pony orm各有特色,SQLAlchemy和peewee都已經(jīng)是很成熟的框架,大量的被應(yīng)用在商業(yè)環(huán)境中?;氐絃unar,既然是造輪子,何不造個(gè)徹底,于是便擼了一個(gè)orm框架出來。

在ORM框架中,我們使用類的定義來表示數(shù)據(jù)庫中的表結(jié)構(gòu),使用類方法避免繁瑣的SQL語句,一個(gè)ORM類定義類似于下面這段代碼:

pyclass Post(db.Model):

    __tablename__ = "post"

    id = database.PrimaryKeyField()
    title = database.CharField(100)
    content = database.TextField()
    pub_date = database.DateField()

    author_id = database.ForeignKeyField("author")
    tags = database.ManyToManyField(rel="post_tag_re", to_table="tag")

    def __repr__(self):
        return "" % self.title

上面這段代碼取自Lunar框架的ORM測(cè)試和一個(gè)博客的example,這段代碼定義了一個(gè)Post類,代表了數(shù)據(jù)庫中的一張表,類中的一系列屬性分別對(duì)應(yīng)著表中的列數(shù)據(jù)。

一個(gè)peewee或者SQLAlchemy類似語法的一個(gè)ORM框架語句類似下面這樣:

py    p = Post.get(id=1)

返回的結(jié)果是Post類的實(shí)例,這個(gè)實(shí)例,p.id返回的不是一個(gè)PrimaryKeyField,而是一個(gè)int類型值,其他的與數(shù)據(jù)庫關(guān)聯(lián)的類屬性也是同樣。

orm框架本質(zhì)上是sql語句或者數(shù)據(jù)庫模式(schema)和python對(duì)象之間的轉(zhuǎn)換器或者翻譯器,這有些類似于編譯器結(jié)構(gòu)。

在這里,Post是我們創(chuàng)建的一個(gè)orm類,post擁有若干數(shù)據(jù)操作方法,通過調(diào)用類似這樣的更加人性化或者直觀的api,代替?zhèn)鹘y(tǒng)的sql語句和對(duì)象映射。orm框架將語句翻譯為sql語句,執(zhí)行,并在最后將語句轉(zhuǎn)換為post類的實(shí)例。

可能從這個(gè)角度看來,實(shí)現(xiàn)orm框架并不是什么tough的任務(wù),讓我們用上面提到的這個(gè)例子來看

py p = Post.get(id=1)

這條語句翻譯成的sql語句為

select * from post where id=1;

可以看到的是,get方法會(huì)使用一個(gè)select語句,翻譯程序?qū)ost類的表名和條件分別組合到select語句中,嗅覺靈敏的pythoner會(huì)發(fā)現(xiàn)這是一個(gè)典型的Post類的classmethod,直接通過類來調(diào)用這個(gè)方法,我們可以快速的寫出這個(gè)函數(shù)的偽代碼:

pyclass Model(Meta):

    ...

    @classmethod
    def get(cls, *args, **kwargs):
        # get method only supposes to be used by querying by id.
        # UserModel.get(id=2)
        # return a single instance.
        sql = "select * from %s"
        if kwargs:
            sql += "where %s"
        rs = db.execute(sql %(cls.__tablename__, " and ".join(["=".join([k, v]) 
            for k, v in kwargs.items()])))
        return make_instance(rs, descriptor) #descriptor describe the format of rs.

從本質(zhì)上,所有的翻譯工作都可以這樣來完成。但是在重構(gòu)后的代碼中可能會(huì)掩蓋掉很多細(xì)節(jié)。

其實(shí)這大概是實(shí)現(xiàn)一個(gè)orm框架的全部了,只是我們還需要一點(diǎn)python中很酷炫的一個(gè)編程概念來解決一個(gè)問題。

考慮實(shí)現(xiàn)ORM框架的create_all方法,創(chuàng)建所有ORM框架規(guī)范下類的實(shí)際數(shù)據(jù)庫表,這是熟悉SQLAlchemy的Pythoner都會(huì)比較熟悉的一個(gè)方法。

create_all方法要求所有繼承了db.Model類的子類全部注冊(cè)在db的一個(gè)屬性中,比如tabledict,這樣create_all方法在調(diào)用時(shí)可以使用db中的tabledict屬性,將所有注冊(cè)的類編譯為SQL語句并執(zhí)行。

直觀的來看,我們需要控制類創(chuàng)建的行為。例如Post類,在這個(gè)類被創(chuàng)建的時(shí)候,將Post類寫入tabledict。

那么怎么控制一個(gè)類被創(chuàng)建的時(shí)候的行為?答案是使用元編程,Python中有多種實(shí)現(xiàn)元編程的方式,descriptor或者metaclass等方式都是實(shí)現(xiàn)元編程的方式,在這里,我們使用元類(metaclass)。關(guān)于metaclass,網(wǎng)絡(luò)上最經(jīng)典的文章莫過于StackOverflow上的這篇回答,強(qiáng)烈推薦給所有的人看。這里我先直接給出偽碼:

pyclass MetaModel(type):
    def __new__(cls, name, bases, attrs):
        cls = super(MetaModel, cls).__new__(cls, name, bases, attrs)

        ...

        cls_dict = cls.__dict__
        if "__tablename__" in cls_dict.keys():
            setattr(cls, "__tablename__", cls_dict["__tablename__"])
        else:
            setattr(cls, "__tablename__", cls.__name__.lower())

        if hasattr(cls, "db"):
            getattr(cls, "db").__tabledict__[cls.__tablename__] = cls

        ...

        return cls

class Model(MetaModel("NewBase", (object, ), {})): #python3 compatibility
    def __init__(self, **kwargs):

        ...

        for k, v in kwargs.items():
            setattr(self, k, v))

        ...

這種方式定義的Model,在創(chuàng)建的時(shí)候,會(huì)由MetaModel控制創(chuàng)建過程,最后返回整個(gè)類,在創(chuàng)建過程中,我們將表名稱和類本身全部塞入了db的一個(gè)屬性中。這樣create_all方法便可以直接使用tabledict中的類屬性直接創(chuàng)建所有的表:

pyclass Database(threading.local):
    ...

    def create_all(self):
        for k, v in self.__tabledict__.items():
            if issubclass(v, self.Model):
                self.create_table(v)

OK,到這里,幾乎ORM的所有核心技術(shù)全部介紹完畢。ORM并不是一個(gè)很tough的工作,但是也并不是很簡(jiǎn)單。ORM框架的實(shí)現(xiàn)是一個(gè)解決一系列問題的過程,其實(shí)思考的過程是最為激動(dòng)人心的。

模板引擎

模板引擎是另外一個(gè)比較大和tough的模塊。Python同樣有很多出色的模板引擎,當(dāng)下最為流行莫過于Mako和Jinja2,國(guó)外的Reddit和國(guó)內(nèi)的豆瓣公司大量的使用了Mako作為模板引擎進(jìn)行網(wǎng)頁渲染。Jinja2因?yàn)榫哂袕?qiáng)大的性能支撐和沙箱模式,在Python社區(qū)中也很流行。

Python模板引擎的核心功能是把標(biāo)記語言編譯成為可執(zhí)行的代碼,執(zhí)行一些邏輯或者操作,返回模板文件的渲染結(jié)果,往往是字符串。模板引擎的實(shí)現(xiàn)同樣類似于傳統(tǒng)的編譯器結(jié)構(gòu),模板引擎首先會(huì)使用一個(gè)詞法分析模塊分析出所有的token,并分類標(biāo)記;在這之后,會(huì)使用一個(gè)類似于編譯器中的語法分析的模塊分析token序列,調(diào)用相應(yīng)的操作,對(duì)于不同的token,我們需要多帶帶編寫一個(gè)處理程序(類似于SDT),來處理token的輸出。

最簡(jiǎn)單的例子:

py    t = lunar.Template("Hello {{ name }}").render(name="lunar")

這段代碼,我們期待的輸出是"Hello lunar",name會(huì)被lunar替換掉。根據(jù)上面我提到的模板引擎的工作流程,首先,我們使用詞法分析程序?qū)@段模板語言做模板編譯,分割所有的字符串(實(shí)際實(shí)現(xiàn)的時(shí)候并非如此),給每個(gè)單詞賦給一個(gè)屬性,例如上面這段模板語言經(jīng)過最基礎(chǔ)的詞法分析會(huì)得到下面這個(gè)結(jié)果:

<"Hello" PlainText>
<" " Operator> # Blank Space
<"name" Variable> 

有了“詞法分析”得到的序列,我們開始遍歷這個(gè)序列中的所有token,對(duì)每一個(gè)token進(jìn)行處理。

pyfor token in tokens:
    if isinstance(token, PlainText):
        processPlainText(token)
    elif isinstance(token, Variable):
        processVariable(token)

    ...

一些模板引擎將模板標(biāo)記語言編譯為Python代碼,使用exec函數(shù)執(zhí)行,最后將結(jié)果嵌套回來。例如上面這段代碼,我們可以依次對(duì)token進(jìn)行類似下面這樣的處理:

pydef processPlainText(token):
    return "_stdout.append("" +token+ "")"

def processVariable(token):
    return "_stdout.append(" + token +")"

看到這里你可能會(huì)覺得莫名其妙,對(duì)于一連串的token序列,經(jīng)過處理后的字符串類似于下面這樣,看完后你的狀態(tài)肯定還是莫名其妙:

pyintermediate = ""
intermediate += "_stdout.append("Hello")"
intermediate += "_stdout.append(" ")"
intermediate += "_stdout.append(name)"

回到上面提到的那個(gè)函數(shù)exec,我們使用exec函數(shù)執(zhí)行上面的這段字符串,這在本質(zhì)上其實(shí)是一種很危險(xiǎn)的行為。exec函數(shù)接受一個(gè)命名空間,或者說上下文(context)參數(shù),我們對(duì)這段代碼做類似下面的處理:

pycontext = {}
context["_stdout"] = []
context["name"] = "lunar"

exec(intermediate, context)

return "".join(context["_stdout"])

context是一個(gè)字典,在真正的模板渲染時(shí),我們把所有需要的上下文參數(shù)全部update到context中,傳給exec函數(shù)進(jìn)行執(zhí)行,exec函數(shù)會(huì)在context中進(jìn)行更改,最后我們可以取到context中經(jīng)過修改后的所有的值。在這里,上面兩個(gè)代碼片段中的_stdout在context中作為一個(gè)空列表存在,所以在執(zhí)行完exec后,context中的stdout會(huì)帶回我們需要的結(jié)果。

具體來看,將render中的context傳入exec,這里exec會(huì)執(zhí)行一個(gè)變換:

_stdout.append(name) -> exec(intermediate, {name:"lunar"}) -> _stdout.append("lunar")

經(jīng)過這個(gè)神奇的變化之后(搞毛,就是替換了一下嘛),我們就得到了模板渲染后需要的結(jié)果,一個(gè)看似是標(biāo)記語言執(zhí)行后的結(jié)果。

讓我們看一個(gè)稍微復(fù)雜一些的模板語句,比如if...else...,經(jīng)過處理后的中間代碼會(huì)類似于下面這樣:


{% if a > 2 %}
    {{ a }}
{% else %}
    {{ a * 3 }}
{% endif %}

中間代碼:

pyintermediate = "_stdout.append("")
"
intermediate += "if a > 2 :
"
intermediate += "   _stdout.append(a)
"
intermediate += "else :
"
intermediate += "   _stdout.append(a * 3)
"
intermediate += "_stdout.append("")"

注意中間代碼中的縮進(jìn)!這是這一類型的模板引擎執(zhí)行控制流的所有秘密,這段代碼就是原生的Python代碼,可執(zhí)行的Python代碼。模板引擎構(gòu)建了一個(gè)從標(biāo)記語言到Python原生語言的轉(zhuǎn)換器,所以模板引擎往往能夠做出一些看似很嚇人,其實(shí)很low的功能,比如直接在模板引擎中寫lambda函數(shù):

pyfrom lunar.template import Template

rendered = Template(
            "{{ list(map(lambda x: x * 2, [1, 2, 3])) }}").render()

但是!深入優(yōu)化后的模板引擎往往沒有這么簡(jiǎn)單,也不會(huì)使用這么粗暴的實(shí)現(xiàn)方式,眾多模板引擎選擇了自己寫解釋程序。把模板語言編譯成AST,然后解析AST,返回結(jié)果。這樣做有幾點(diǎn)好處:

自定義模板規(guī)則

利于性能調(diào)優(yōu),比如C語言優(yōu)化

當(dāng)然,模板引擎界也有桑心病狂者,使用全部的C來實(shí)現(xiàn),比如同樣很有名的Cheetah。

或許因?yàn)榇a很小的原因,我在Lunar中實(shí)現(xiàn)的這個(gè)模板引擎在多個(gè)benchmark測(cè)試下展現(xiàn)了還不錯(cuò)的性能,具體的benchmark大家可以在項(xiàng)目的template測(cè)試中找到,自己運(yùn)行一下,這里給出一個(gè)基于我的機(jī)器的性能測(cè)試結(jié)果:

第一個(gè)結(jié)果是Jonas BorgstrOm為SpitFire所寫的benchmarks:

Linux Platform
-------------------------------------------------------
Genshi tag builder                            239.56 ms
Genshi template                               133.26 ms
Genshi template + tag builder                 261.40 ms
Mako Template                                  44.64 ms
Djange template                               335.10 ms
Cheetah template                               29.56 ms
StringIO                                       33.63 ms
cStringIO                                       7.68 ms
list concat                                     3.25 ms
Lunar template                                 23.46 ms
Jinja2 template                                 8.41 ms
Tornado Template                               24.01 ms
-------------------------------------------------------

Windows Platform
-------------------------------------------------------
Mako Template                                 209.74 ms
Cheetah template                              103.80 ms
StringIO                                       42.96 ms
cStringIO                                      11.62 ms
list concat                                     4.22 ms
Lunar template                                 27.56 ms
Jinja2 template                                27.16 ms
-------------------------------------------------------

第二個(gè)結(jié)果是Jinja2中mitsuhiko的benchmark測(cè)試:

    Linux Platform:
    ----------------------------------
    jinja               0.0052 seconds
    mako                0.0052 seconds
    tornado             0.0200 seconds
    django              0.2643 seconds
    genshi              0.1306 seconds
    lunar               0.0301 seconds
    cheetah             0.0256 seconds
    ----------------------------------

    Windows Platform:
    ----------------------------------
    ----------------------------------

    jinja               0.0216 seconds
    mako                0.0206 seconds
    tornado             0.0286 seconds
    lunar               0.0420 seconds
    cheetah             0.1043 seconds
    -----------------------------------

這個(gè)結(jié)果最吸引我的有下面幾點(diǎn):

Jinja2真(TM)快!

Django真慢!

Mako的實(shí)現(xiàn)肯定有特殊的優(yōu)化點(diǎn),不同的benchmark差距過大!

現(xiàn)在Lunar的代碼還很臟,而且可以重構(gòu)的地方還很多,相信重構(gòu)后性能還會(huì)上一個(gè)臺(tái)階(誰知道呢?)。

Router

Router負(fù)責(zé)整個(gè)web請(qǐng)求的轉(zhuǎn)發(fā),將一個(gè)請(qǐng)求地址和處理函數(shù)匹配在一起。主流的Router有兩種接口類型,一種是Django和Tornado類型的"字典式":

pyurl_rules = {
    "/": index,
    "/post/d": post,
}

另外一種是Flask和Bottle這種小型框架偏愛的裝飾器(decorator)類型的router:

py@app.route("/")
def index():
    pass

@app.route("/post/")
def post(id):
    pass

router的實(shí)現(xiàn)還是很簡(jiǎn)單的,router的本質(zhì)就是一個(gè)字典,把路由規(guī)則和函數(shù)連接在一起。這里有一些麻煩的是處理帶參數(shù)的路由函數(shù),例如上例中,post的id是可以從路由調(diào)用地址中直接獲得的,調(diào)用/post/12會(huì)調(diào)用函數(shù)post(12),在這里,傳參是較為麻煩的一點(diǎn)。另外的一個(gè)難點(diǎn)是redirect和url_for的實(shí)現(xiàn):

py return redirect(url_for(post, 1))

但其實(shí)也不難啦,感興趣的可以看一下代碼的實(shí)現(xiàn)。

Router的另外一個(gè)注意點(diǎn)是,使用裝飾器方式實(shí)現(xiàn)的路由需要在app跑起來之前,讓函數(shù)都注冊(cè)到router中,所以往往需要一些很奇怪的代碼,例如我在Lunar項(xiàng)目的example中寫了一個(gè)blog,blog的init文件是像下面這樣定義的:

pyfrom lunar import lunar
from lunar import database

app = lunar.Lunar("blog")
app.config["DATABASE_NAME"] = "blog.db"

db = database.Sqlite(app.config["DATABASE_NAME"])

from . import views

注意最后一行,最后一行代碼需要import views中的所有函數(shù),這樣views中的函數(shù)才會(huì)注冊(cè)到router中。這個(gè)痛點(diǎn)在Flask中同樣存在。

WSGI

最后的最后,我們實(shí)現(xiàn)了這么多組件,我們還是需要來實(shí)現(xiàn)Python請(qǐng)求中最核心和基本的東西,一個(gè)WSGI接口:

pydef app(environ, start_response):
     start_response("200 OK", [("Content-Type", "text/plain")])
     yield "Hello world!
"

WSGI接口很簡(jiǎn)單,實(shí)現(xiàn)一個(gè)app,接受兩個(gè)參數(shù)environ和start_response,想返回什么就返回什么好了。關(guān)于WSGI的詳細(xì)信息,可以查看PEP333和PEP3333。這里我說幾點(diǎn)對(duì)WSGI這個(gè)東西自己的理解:

計(jì)算機(jī)服務(wù),或者說因特網(wǎng)服務(wù)的核心是什么?現(xiàn)在的我,會(huì)給出協(xié)議這個(gè)答案。我們會(huì)發(fā)現(xiàn),計(jì)算機(jī)的底層,網(wǎng)絡(luò)通信的底層都是很簡(jiǎn)單、很樸素的東西,無非是一些0和1,一些所謂字符串罷了。去構(gòu)成這些服務(wù),把我們連接在一起的是我們解釋這些樸素的字符串的方式,我們把它們稱為協(xié)議。

WSGI同樣是一個(gè)協(xié)議,WSGI最大的優(yōu)勢(shì)是,所有實(shí)現(xiàn)WSGI接口的應(yīng)用均可以運(yùn)行在WSGI server上。通過這種方式,實(shí)現(xiàn)了Python WSGI應(yīng)用的可移植。Django和Flask的程序可以混編在一起,在一個(gè)環(huán)境上運(yùn)行。在我實(shí)現(xiàn)的框架Lunar中,使用了多種WSGI server進(jìn)行測(cè)試。

在一些文章中,把類似于router,template engine等組件,包裝在網(wǎng)絡(luò)框架之中,WSGI應(yīng)用之上的這些組件成為WSGI中間件,得益于WSGI接口的簡(jiǎn)單,編寫WSGI中間件變得十分簡(jiǎn)單。在這里,最難的問題是如何處理各個(gè)模塊的解耦。

考慮之前提到的模板引擎和ORM framework的實(shí)現(xiàn),模板引擎和數(shù)據(jù)庫ORM都需要獲取應(yīng)用的上下文(context),這是實(shí)現(xiàn)整個(gè)框架的難點(diǎn)。也是項(xiàng)目未來重構(gòu)的核心問題。

結(jié)

現(xiàn)在代碼之爛是讓我無法忍受的。最近開始讀兩本書,代碼整潔之道和重構(gòu),自己在處理大型的軟件體系,處理很多設(shè)計(jì)模式的問題的時(shí)候還是很弱逼。首先會(huì)拿模板引擎開刀,我有一個(gè)大體重構(gòu)的方案,會(huì)很快改出來,力爭(zhēng)去掉parser中的大條件判斷,并且嘗試做一些性能上的優(yōu)化。

Lunar是一個(gè)學(xué)習(xí)過程中的實(shí)驗(yàn)品,這么無聊,總是要寫一些代碼的,免得畢業(yè)后再失了業(yè)。

在最后,還是要感謝亮叔https://github.com/skyline75489,亮叔是我非常崇拜的一個(gè)Pythoner,或者說coder,一名天生的軟件工匠。沒有他這個(gè)項(xiàng)目不會(huì)有這么高的完整度,他改變了我對(duì)這個(gè)項(xiàng)目的態(tài)度。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/45313.html

相關(guān)文章

  • 用JS 重新造了個(gè)輪子,農(nóng)歷計(jì)算腳本,有詳細(xì)注釋

    摘要:在重新造輪子之前,準(zhǔn)備對(duì)性能優(yōu)化下。最重要的,只寫農(nóng)歷計(jì)算相關(guān)的計(jì)算,其他無功能,如果需要,通過本腳本。為除了閏月外的正常月份是大月還是小月,為天,為天。表示閏月是大月還是小月,僅當(dāng)存在閏月的情況下有意義。 工作中有時(shí)需要農(nóng)歷計(jì)算,之前從網(wǎng)上找了個(gè)JS版本的(摘自wannianli.htm,網(wǎng)上導(dǎo)出都是),直接調(diào)用就可以了,非常方便。有優(yōu)點(diǎn)就有缺點(diǎn),該版本文件有點(diǎn)大(20KB以上);有...

    zhigoo 評(píng)論0 收藏0
  • 全面整理30個(gè)重要深度學(xué)習(xí)庫:按Python和C++等10種語言分類

    摘要:本文介紹了包括等在內(nèi)的一系列編程語言的深度學(xué)習(xí)庫。是一個(gè)在中用于帶有神經(jīng)網(wǎng)絡(luò)的深度學(xué)習(xí)的庫,它通過使用帶有的加速。是一個(gè)用和開發(fā)的深度學(xué)習(xí)庫。是第一個(gè)為和編寫的消費(fèi)級(jí)開元分布式深度學(xué)習(xí)庫。它帶有豐富的作為機(jī)器學(xué)習(xí)庫一部分的深度學(xué)習(xí)庫。 本文介紹了包括 Python、Java、Haskell等在內(nèi)的一系列編程語言的深度學(xué)習(xí)庫。PythonTheano 是一種用于使用數(shù)列來定義和評(píng)估數(shù)學(xué)表達(dá)的 ...

    weij 評(píng)論0 收藏0
  • 基于 10 大編程語言 30 個(gè)深度學(xué)習(xí)庫

    摘要:本文介紹了包括等在內(nèi)的一系列編程語言的深度學(xué)習(xí)庫。是一個(gè)部署在編程語言中的深度學(xué)習(xí)工具包,用于通過高效的算法處理大型文本集。是公司基于開發(fā)的深度學(xué)習(xí)框架。是第一個(gè)為和編寫的消費(fèi)級(jí)開元分布式深度學(xué)習(xí)庫。 本文介紹了包括 Python、Java、Haskell等在內(nèi)的一系列編程語言的深度學(xué)習(xí)庫。PythonTheano 是一種用于使用數(shù)列來定義和評(píng)估數(shù)學(xué)表達(dá)的 Python 庫。它可以讓 Pyt...

    Winer 評(píng)論0 收藏0
  • 精通Python網(wǎng)絡(luò)爬蟲(0):網(wǎng)絡(luò)爬蟲學(xué)習(xí)路線

    摘要:以上是如果你想精通網(wǎng)絡(luò)爬蟲的學(xué)習(xí)研究路線,按照這些步驟學(xué)習(xí)下去,可以讓你的爬蟲技術(shù)得到非常大的提升。 作者:韋瑋 轉(zhuǎn)載請(qǐng)注明出處 隨著大數(shù)據(jù)時(shí)代的到來,人們對(duì)數(shù)據(jù)資源的需求越來越多,而爬蟲是一種很好的自動(dòng)采集數(shù)據(jù)的手段。 那么,如何才能精通Python網(wǎng)絡(luò)爬蟲呢?學(xué)習(xí)Python網(wǎng)絡(luò)爬蟲的路線應(yīng)該如何進(jìn)行呢?在此為大家具體進(jìn)行介紹。 1、選擇一款合適的編程語言 事實(shí)上,Python、P...

    spacewander 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<