1. 程式人生 > >Python中的__get__與__set__

Python中的__get__與__set__

1、__get__的用法

  參見:https://www.cnblogs.com/saolv/p/6890645.html

2、Flask中的使用

2.1、Flask中原始碼

  Flask類:

  內建的配置值定義參見:http://www.pythondoc.com/flask/config.html

class Flask(_PackageBoundObject):
	testing = ConfigAttribute('TESTING')
	secret_key = ConfigAttribute('SECRET_KEY')
	session_cookie_name = ConfigAttribute('SESSION_COOKIE_NAME')
	permanent_session_lifetime = ConfigAttribute('PERMANENT_SESSION_LIFETIME',
        get_converter=_make_timedelta)
	send_file_max_age_default = ConfigAttribute('SEND_FILE_MAX_AGE_DEFAULT',
        get_converter=_make_timedelta)
	use_x_sendfile = ConfigAttribute('USE_X_SENDFILE')
	env = ConfigAttribute('ENV')

  ConfigAttribute類:

class ConfigAttribute(object):
    """Makes an attribute forward to the config"""

    def __init__(self, name, get_converter=None):
        self.__name__ = name
        self.get_converter = get_converter

    def __get__(self, obj, type=None):
        print("__get__() is called", obj, type)
        if obj is None:
            return self
        rv = obj.config[self.__name__]
        if self.get_converter is not None:
            rv = self.get_converter(rv)
        return rv

    def __set__(self, obj, value):
        print("__set__() is called", obj, value)
        obj.config[self.__name__] = value

2.2、測試用Flask程式

from flask import Flask,Response
from settings import config

app = Flask(__name__)


app.config.from_object(config['default'])

print("*"*50)
print(app.secret_key)
app.secret_key = "123"
print("*"*50)
print(app.session_cookie_name)
app.session_cookie_name = "session_ok"
print("*"*50)

@app.route('/home/')
def home():
    return Response("home,hello")

if __name__ == "__main__":
    app.run()

  

  setting.py源程式:

import os
import logging
import datetime

# print(__file__)
# print(os.path.dirname(__file__))
basedir = os.path.abspath(os.path.dirname(__file__))
# print(basedir)

class InfoFilter(logging.Filter):
    def filter(self, record):
        """
        only use INFO
        篩選,只需要INFO級別的log
        :param record:
        :return:
        """
        if logging.INFO <= record.levelno <logging.ERROR:
            # 已經是INFO級別了
            # 然後利用父類,返回1
            return super().filter(record)
        else:
            return 0


class BaseConfig(object):
    DEBUG = False
    TESTING = False
    PROPAGATE_EXCEPTIONS = None
    PRESERVE_CONTEXT_ON_EXCEPTION = None
    SECRET_KEY = None
    PERMANENT_SESSION_LIFETIME = datetime.timedelta(31)
    USE_X_SENDFILE = False
    LOGGER_NAME = "app"
    LOGGER_HANDLER_POLICY = "always"
    SERVER_NAME = None
    APPLICATION_ROOT = None
    SESSION_COOKIE_NAME = "session"
    SESSION_COOKIE_DOMAIN = None
    SESSION_COOKIE_PATH = None
    SESSION_COOKIE_HTTPONLY = True
    SESSION_COOKIE_SECURE = False
    SESSION_REFRESH_EACH_REQUEST = True
    MAX_CONTENT_LENGTH = None
    SEND_FILE_MAX_AGE_DEFAULT =  datetime.timedelta(0, 43200)
    TRAP_BAD_REQUEST_ERRORS = False
    TRAP_HTTP_EXCEPTIONS = False
    EXPLAIN_TEMPLATE_LOADING = False
    PREFERRED_URL_SCHEME = 'http'
    JSON_AS_ASCII = True
    JSON_SORT_KEYS = True
    JSONIFY_PRETTYPRINT_REGULAR = True
    JSONIFY_MIMETYPE = 'application / json'
    TEMPLATES_AUTO_RELOAD = None

    LOG_PATH = os.path.join(basedir, 'logs')
    LOG_PATH_ERROR = os.path.join(LOG_PATH, 'error.log')
    LOG_PATH_INFO = os.path.join(LOG_PATH, 'info.log')
    LOG_FILE_MAX_BYTES =100*1024*1024
    # 輪轉數量是10個
    LOG_FILE_BACKUP_COUNT = 10

    @classmethod
    def init_app(cls, app):
        pass

class ProductionConfig(BaseConfig):
    DEBUG = False

class DevelopmentConfig(BaseConfig):

    DEBUG = True
    SECRET_KEY = "avafaewffewfaew"

    @classmethod
    def init_app(cls, app):
        # BaseConfig.init_app(app)
        super().init_app(app)

        import logging
        from logging.handlers import RotatingFileHandler
        # Formatter
        formatter = logging.Formatter(
            '%(asctime)s %(levelname)s %(process)d %(thread)d '
            '%(pathname)s %(lineno)s %(message)s')

        # FileHandler Info
        file_hander_info = RotatingFileHandler(filename=cls.LOG_PATH_INFO)
        file_hander_info.setFormatter(formatter)
        file_hander_info.setLevel(logging.INFO)
        info_filter = InfoFilter()
        file_hander_info.addFilter(info_filter)
        app.logger.addHandler(file_hander_info)

        # FileHandler Error
        file_hander_error = RotatingFileHandler(filename=cls.LOG_PATH_ERROR)
        file_hander_error.setFormatter(formatter)
        file_hander_error.setLevel(logging.ERROR)
        app.logger.addHandler(file_hander_error)



class TestConfig(BaseConfig):

    DEBUG = True

config = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'testing': TestConfig,
    'default': DevelopmentConfig,
}

2.3、執行測試程式

  列印輸出:

**************************************************
__get__() is called <Flask '__get__與__set__'> <class 'flask.app.Flask'>
avafaewffewfaew
__set__() is called <Flask '__get__與__set__'> 123
**************************************************
__get__() is called <Flask '__get__與__set__'> <class 'flask.app.Flask'>
session
__set__() is called <Flask '__get__與__set__'> session_ok
**************************************************
__get__() is called <Flask '__get__與__set__'> <class 'flask.app.Flask'>