溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

自定義session

發(fā)布時間:2020-08-08 01:02:17 來源:網(wǎng)絡(luò) 閱讀:427 作者:justforid 欄目:開發(fā)技術(shù)

自定義Session

a.知識儲備

         #!/usr/bin/env python

         # -*- coding:utf-8 -*-

          

         class Foo(object):

             def __getitem__(self, key):

                  print  '__getitem__',key

          

             def __setitem__(self, key, value):

                  print '__setitem__',key,value

          

             def __delitem__(self, key):

                  print '__delitem__',key

          

         obj = Foo()

         result = obj['k1']  會執(zhí)行Foo類的 __getitem__方法

         obj['k2'] = 'wupeiqi' 會執(zhí)行Foo類的 __setitem__方法

         del obj['k1']     會執(zhí)行Foo類的 __delitem__方法

         類常用的內(nèi)置方法

         __init__(self,......):初始化對象,在創(chuàng)建新對象前申明

         __del__(self):釋放對象,在對象被刪除之前調(diào)用

         __new__(self,*args,**ked):實例的生產(chǎn)操作

         __str__(self):在使用print語句時調(diào)用

         __delitem__(self,key):為字典中刪除key對應(yīng)的元素

         __setitem__(self,key,value):為字典中的key賦值

         __getitem__(self,key):獲取序列的索引key對應(yīng)的值,等價于seq[key]

         __len__(self):在調(diào)用內(nèi)聯(lián)函數(shù)len()時被調(diào)用

         __cmp__(src,dst):比較兩個對象srcdst

         __getattr__(s,name):獲取屬性的值

         __setattr__(s,name):設(shè)置屬性的值

         __gt__(self,other):判斷self對象是否大于other對象

         __lt__(self,other):判斷self對象是否小于other對象

         __ge__(self,other):判斷self對象是否不大于other對象

         __le__(self,other):判斷self對象是否不小于other對象

         __eq__(self,other):判斷self對象是否等于other對象

         __call__(self,*args):把實例對象作為函數(shù)調(diào)用

 

         __new__():

    __new__()__init__()之前被調(diào)用,用于生成實例對象.利用這個方法和類屬性的特性可以實現(xiàn)設(shè)計模式中的單例模式.單例模式是指創(chuàng)建唯一對象,單例模式設(shè)計的類只能實例化一個對象.

    #!/usr/bin/python

    # -*- coding: UTF-8 -*-

    class Singleton(object):

        __instance = None                       # 定義實例

        def __init__(self):

            pass

        def __new__(cls, *args, **kwd):         # __init__之前調(diào)用

            if Singleton.__instance is None:    # 生成唯一實例

                Singleton.__instance = object.__new__(cls, *args, **kwd)

            return Singleton.__instance

 

         __getattr__()__setattr__()__getattribute__():

    當讀取對象的某個屬性時,python會自動調(diào)用__getattr__()方法.例如,fruit.color將轉(zhuǎn)換為fruit.__getattr__(color).當使用賦值語句對屬性進行設(shè)置時,python會自動調(diào)用__setattr__()方法.__getattribute__()的功能與__getattr__()類似,用于獲取屬性的值.但是__getattribute__()能提供更好的控制,代碼更健壯.注意,python中并不存在__setattribute__()方法.

    代碼例子:

 

    #!/usr/bin/python

    # -*- coding: UTF-8 -*-

    class Fruit(object):

        def __init__(self, color = "red", price = 0):

            self.__color = color

            self.__price = price

           

        def __getattribute__(self, name):               # 獲取屬性的方法

            return object.__getattribute__(self, name)

 

        def __setattr__(self, name, value):

            self.__dict__[name] = value

 

    if __name__ == "__main__":

        fruit = Fruit("blue", 10)

        print fruit.__dict__.get("_Fruit__color")       # 獲取color屬性

        fruit.__dict__["_Fruit__price"] = 5

        print fruit.__dict__.get("_Fruit__price")       # 獲取price屬性

 

             __getitem__()、__setitem__()__delitem_():

        如果類把某個屬性定義為序列(列表、字典等),可以使用__getitem__()輸出序列屬性中的某個元素.假設(shè)水果店中銷售多鐘水果,可以通過__getitem__()方法獲取水果店中的每種水果,__setitem__()來設(shè)置,

        代碼例子,:

        #!/usr/bin/python

        # -*- coding: UTF-8 -*-

        class FruitShop:

         def __getitem__(self, i):      # 獲取水果店的水果

             print '__getitem__'

             return self.fruits[i]

         def __setitem__(self,key,value):

             self.fruits[key] = value

             print '__setitem__'

 

    if __name__ == "__main__":

        shop = FruitShop()

        shop.fruits = {}

        shop['apple'] = 'red' #["apple", "banana"]

        print shop['apple']

 

        輸出為:

        __setitem__

        __getitem__

        red

 

         __str__():

    __str__()用于表示對象代表的含義,返回一個字符串.實現(xiàn)了__str__()方法后,可以直接使用print語句輸出對象,也可以通過函數(shù)str()觸發(fā)__str__()的執(zhí)行.這樣就把對象和字符串關(guān)聯(lián)起來,便于某些程序的實現(xiàn),可以用這個字符串來表示某個類

    代碼例子:

    #!/usr/bin/python

    # -*- coding: UTF-8 -*-

    class Fruit:     

        '''Fruit'''               #Fruit類定義了文檔字符串

        def __str__(self):          # 定義對象的字符串表示

            return self.__doc__

 

    if __name__ == "__main__":

        fruit = Fruit()

        print str(fruit)            # 調(diào)用內(nèi)置函數(shù)str()出發(fā)__str__()方法,輸出結(jié)果為:Fruit

        print fruit                 #直接輸出對象fruit,返回__str__()方法的值,輸出結(jié)果為:Fruit

 

      

    __call__():

    在類中實現(xiàn)__call__()方法,可以在對象創(chuàng)建時直接返回__call__()的內(nèi)容.使用該方法可以模擬靜態(tài)方法

    代碼例子:

    #!/usr/bin/python

    # -*- coding: UTF-8 -*-

    class Fruit:

        class Growth:        # 內(nèi)部類

            def __call__(self):

                print "grow ..."

 

        grow = Growth()      # 調(diào)用Growth(),此時將類Growth作為函數(shù)返回,即為外部類Fruit定義方法grow(),grow()將執(zhí)行__call__()內(nèi)的代碼

    if __name__ == '__main__':

        fruit = Fruit()

        fruit.grow()         # 輸出結(jié)果:grow ...

        Fruit.grow()         # 輸出結(jié)果:grow ...

 

 

b.session實現(xiàn)機制

    #!/usr/bin/env python

    # -*- coding:utf-8 -*-

     

    import tornado.ioloop

    import tornado.web

    from hashlib import sha1

    import os, time

     

    session_container = {}

     

    create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest()  #創(chuàng)建一個函數(shù),生成session_id

        #os.urandom(n) 返回n個隨機byte值的string,作為加密使用

       

    class Session(object):

     

        session_id = "__sessionId__"

     

        def __init__(self, request):

            session_value = request.get_cookie(Session.session_id) #從客戶端傳過來的cookie中取session_id

            if not session_value:  #如果沒有,就生成一個,賦給self._id

                self._id = create_session_id()

            else:

                self._id = session_value  #如果有,就取出來賦給self._id

            request.set_cookie(Session.session_id, self._id)  #設(shè)置cookie

     

        def __getitem__(self, key):   #session[key]時返回 session_container[self._id][key]

            return session_container[self._id][key]

     

        def __setitem__(self, key, value): #設(shè)置session[key],就是設(shè)置 session_container[self._id]key值等于value

            if session_container.has_key(self._id):  #如果self._id已經(jīng)在sessiion_container里,就直接設(shè)置

                session_container[self._id][key] = value

            else:                  #如果不在,就創(chuàng)建字典并賦值

                session_container[self._id] = {key: value}

     

        def __delitem__(self, key):    #刪除session[key]時,刪掉session_container[self._id][key]

            del session_container[self._id][key]

     

     

    class BaseHandler(tornado.web.RequestHandler):

     

        def initialize(self):

            # my_session['k1']訪問 __getitem__ 方法

            self.my_session = Session(self)  #創(chuàng)建類Session的對象my_session  

     

     

    class MainHandler(BaseHandler):

     

        def get(self):

            print self.my_session['c_user']  #返回 session_container[session_id]['c_user']的值

            print self.my_session['c_card']  #返回 session_container[session_id]['c_card']的值

            self.write('index')

     

    class LoginHandler(BaseHandler):

     

        def get(self):

            self.render('login.html', **{'status': ''})  #打開登錄頁面,返回的status為空

     

        def post(self, *args, **kwargs):

     

            username = self.get_argument('name')  

            password = self.get_argument('pwd')

            if username == 'wupeiqi' and password == '123': #判斷提交的用戶名和密碼,如果正確

     

                self.my_session['c_user'] = 'wupeiqi'  #設(shè)置session_container[session_id]['c_user']='wupeiqi'

                self.my_session['c_card'] = '12312312309823012' #設(shè)置session_container[session_id]['c_card']='12312312309823012'

     

                self.redirect('/index') #重定向到 mainhandler

            else:

                self.render('login.html', **{'status': '用戶名或密碼錯誤'})  #如果用戶名密碼不匹配,返回用戶名或密碼錯誤

     

    settings = {  #配置信息

        'template_path': 'template',     #模板路徑

        'static_path': 'static',       #靜態(tài)文件路徑

        'static_url_prefix': '/static/',      #靜態(tài)文件路徑別名 

        'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',   #設(shè)置cookie的加密碼

        'login_url': '/login'  

    }

     

    application = tornado.web.Application([  #路由規(guī)則

        (r"/index", MainHandler), 

        (r"/login", LoginHandler),

    ], **settings)

     

     

    if __name__ == "__main__":   

        application.listen(8888)     #監(jiān)聽8888端口

        tornado.ioloop.IOLoop.instance().start()  #啟動服務(wù)

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI