目录:

  • 涉及知识点
  • Flask框架原理
  • 简单示例
  • 路由系统原理源码分析
  • 请求流程简单源码分析
  • 响应流程简单源码分析
  • session简单源码分析

涉及知识点

1、装饰器

闭包思想

def wapper(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner """
1. 立即执行wapper函数,并将下面装饰的函数当做参数传递
2. 将wapper函数返回值获取,在index赋值
index = inner函数
"""
@wapper
def index():
print('函数内容') # 实际执行的 inner函数,inner函数内部调用原函数
index()

ps.@functools.wraps,以上我们知道了python实现闭包,实际是index = inner(index)的封装思想。但不可避免的是inner封装后,会对封装的函数隐藏一些信息。如:包装异常,隐藏异常,打印日志,统计函数使用时间等。@functools.wraps通过update_wrapper函数,用参数wrapped表示的函数对象(例如:square)的一些属性(如:__name__、 __doc__)覆盖参数wrapper表示的函数对象(例如:callf,这里callf只是简单地调用square函数,因此可以说callf是 square的一个wrapper function)的这些相应属性。

import functools
def wapper(func):
@functools.wraps(func)
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner @wapper
def index():
print('函数内容') @wapper
def order():
print('函数内容') print(index.__name__)
print(order.__name__)

2、面向对象封装

class Foo(object):
def __init__(self,age,name):
self.age = age
self.name = name class Bar(object):
def __init__(self,counter):
self.counter = counter
self.obj = Foo('','石鹏') b1 = Bar(1)
print(b1.obj.name)

3、python对象什么后面可以加括号

- 函数
- 类
- 方法
- 对象
def f1():
print('f1') class F2(object):
pass class F3(object):
def __init__(self):
pass def ff3(self):
print('ff3') class F4(object):
def __init__(self):
pass def __call__(self, *args, **kwargs):
print('f4') def func(arg):
"""
由于arg在函数中加括号,所以他只有4中表现形式:
- 函数
- 类
- 方法
- 对象
:param arg:
:return:
"""
arg() # 1. 函数,内部执行函数
func(f1)
# 2. 类,内部执行__init__方法
func(F2) # 3. 方法,obj.ff3
obj1 = F3()
func(obj1.ff3) # 4. 对象
obj2 = F4()
func(obj2)

4、call方法

class F4(object):
def __init__(self):
print('构造方法') def __call__(self, *args, **kwargs):
print('f4') def run(self,str1):
print("run:%s" % str1) obj = F4()
obj()
obj.run('sssss')

5、函数和方法的区别

在于调用时有没有实例化对象,即跟某个对象关联。

from types import MethodType,FunctionType

class F3(object):
def __init__(self):
pass def ff3(self):
print('ff3') #
v1 = isinstance(F3.ff3,MethodType) # 方法
v2 = isinstance(F3.ff3,FunctionType) # 函数
print(v1,v2) # False,True obj = F3()
v1 = isinstance(obj.ff3,MethodType) # 方法
v2 = isinstance(obj.ff3,FunctionType) # 函数
print(v1,v2) # True False

Flask框架原理

1、框架本质为通过socket模块实现工作流的请求和响应。

通过socket建立实例,accept等待请求地址,并通过编写路由系统来给予相应的响应。

import socket

def main():
# 创建老师
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8000))
sock.listen(5) while True:
# 老师等待 用户请求的到来
connection, address = sock.accept() # 获取发送的内容:吴亦凡有没有女朋友?
buf = connection.recv(1024) # 根据请求URL的不同:
# 回答:没有
connection.send(b"HTTP/1.1 200 OK\r\n\r\n")
connection.send(b"No No No") # 关闭连接
connection.close() if __name__ == '__main__':
main()

2、flask通过werkzeug模块来帮助我们完成socket性能。

"""
from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple @Request.application
def hello(request):
return Response('Hello World!') if __name__ == '__main__':
# 当请求打来之后,自动执行:hello()
run_simple('localhost', 4000, hello)
""" from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple class Foo(object):
def __call__(self, *args, **kwargs):
return Response('Hello World!') if __name__ == '__main__':
# 当请求打来之后,自动执行:hello()
obj = Foo()
run_simple('localhost', 4000, obj)

3、flask快速入门

"""
pip install flask
pip3 install flask
""" from flask import Flask
# 1. 实例化Flask对象
app = Flask('xxxx') """
1. 执行 app.route('/index')并获取返回值 xx
2.
@xx
def index():
return 'Hello World'
3. 执行 index = xx(index)
本质:
{
'/index': index
}
"""
@app.route('/index')
def index():
return 'Hello World' if __name__ == '__main__':
app.run()

简单示例

1、实现简单登陆

import functools
from flask import Flask,render_template,request,redirect,session app = Flask('xxxx',template_folder="templates")
app.secret_key = 'as923lrjks9d8fwlkxlduf' def auth(func):
@functools.wraps(func)
def inner(*args,**kwargs):
user_info = session.get('user_info')
if not user_info:
return redirect('/login')
return func(*args,**kwargs)
return inner """
{
/order: inner函数, name: order
/index: inner函数, name: index
}
""" @app.route('/order',methods=['GET'])
@auth
def order():
user_info = session.get('user_info')
if not user_info:
return redirect('/login') return render_template('index.html') @app.route('/index',methods=['GET'])
@auth
def index():
return render_template('index.html') @app.route('/login',methods=['GET','POST'])
def login():
if request.method == "GET":
return render_template('login.html')
else:
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'alex' and pwd == '':
session['user_info'] = user
return redirect('/index')
# return render_template('login.html',msg = "用户名或密码错误",x = 123)
return render_template('login.html',**{'msg':'用户名或密码错误'}) @app.route('/logout',methods=['GET'])
def logout():
del session['user_info']
return redirect('/login') if __name__ == '__main__':
app.run()

app.py

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登录页面</h1>
<form method="post">
<input type="text" name="user">
<input type="password" name="pwd">
<input type="submit" value="提交">{{msg}}
</form>
</body>
</html>

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>欢迎进入系统</h1>
<img src="/static/111.png" alt="">
</body>
</html>

templates/index.html

2、flask配置文件

import functools
from flask import Flask # 配置:模板/静态文件
app = Flask('xxxx',template_folder="templates")
# 配置:secret_key
app.secret_key = 'as923lrjks9d8fwlkxlduf' # 导入配置文件
app.config.from_object('settings.TestingConfig') @app.route('/index')
def index():
return "index" if __name__ == '__main__':
app.run()
class BaseConfig(object):
DEBUG = False
SESSION_REFRESH_EACH_REQUEST = True class ProConfig(BaseConfig):
pass class DevConfig(BaseConfig):
DEBUG = True class TestingConfig(BaseConfig):
DEBUG = True

settings.py

ps.import importlib模块,模块支持传递字符串来导入模块。我们先来创建一些简单模块一遍演示。我们在模块里提供了相同接口,通过打印它们自身名字来区分。可通过importlib.import_module(module_path)来动态导入。其等价于import module_path。

路由系统原理源码分析

1、总体流程:

1.初始化Flask类,Rule类,Map类

2.调用app.route方法

3.route方法调用add_url_rule方法

4. add_url_rule方法rule = self.url_rule_class调用Rule方法,封装url和试图函数

5.add_url_rule方法调用url_map.add(Rule)对路由的rules进行添加[Rule('/index', 函数),]

6.map类存到self.url_map中,Rule存在url_rule_class中

import functools
from flask import Flask,views # 配置:模板/静态文件
app = Flask('xxxx',template_folder="templates")
"""
{
'/index': index函数
} 1. decorator = app.route('/index')
2.
@decorator
def index():
return "index"
3. decorator(index)
""" """
Map() = [
Rule(rule=/index/ endpoint=None view_func=函数),
]
"""
@app.route('/index')
def index():
return "index" """
Map() = [
Rule(rule=/index endpoint=None view_func=函数),
Rule(rule=/order endpoint=None view_func=order),
]
"""
def order():
return 'Order'
app.add_url_rule('/order', None, order) class TestView(views.View):
methods = ['GET']
def dispatch_request(self):
return 'test!' app.add_url_rule('/test', view_func=TestView.as_view(name='test')) # name=endpoint
# app.add_url_rule('/test', view_func=view函数) # name=endpoint def auth(func):
def inner(*args, **kwargs):
print('before')
result = func(*args, **kwargs)
print('after')
return result
return inner class X1View(views.MethodView):
methods = ['GET','POST']
decorators = [auth, ] def get(self):
return 'x1.GET' def post(self):
return 'x1.POST' app.add_url_rule('/x1', view_func=X1View.as_view(name='x1')) # name=endpoint if __name__ == '__main__':
app.run()

2、初始化Flask类,Rule类,Map类

#--------------------------------------
# Flask类
class Flask(_PackageBoundObject):
url_rule_class = Rule
def __init__(self, import_name, static_path=None, static_url_path=None,
static_folder='static', template_folder='templates',
instance_path=None, instance_relative_config=False,
root_path=None)
self.url_map = Map() #--------------------------------------
# Role类
@implements_to_string
class Rule(RuleFactory):
def __init__(self, string, defaults=None, subdomain=None, methods=None,
build_only=False, endpoint=None, strict_slashes=None,
redirect_to=None, alias=False, host=None):
if not string.startswith('/'):
raise ValueError('urls must start with a leading slash')
self.rule = string
self.is_leaf = not string.endswith('/') self.map = None
self.strict_slashes = strict_slashes
self.subdomain = subdomain
self.host = host
self.defaults = defaults
self.build_only = build_only
self.alias = alias
if methods is None:
self.methods = None
else:
if isinstance(methods, str):
raise TypeError('param `methods` should be `Iterable[str]`, not `str`')
self.methods = set([x.upper() for x in methods])
if 'HEAD' not in self.methods and 'GET' in self.methods:
self.methods.add('HEAD')
self.endpoint = endpoint
self.redirect_to = redirect_to if defaults:
self.arguments = set(map(str, defaults))
else:
self.arguments = set()
self._trace = self._converters = self._regex = self._weights = None #-------------------
#map类
class Map(object):
default_converters = ImmutableDict(DEFAULT_CONVERTERS) def __init__(self, rules=None, default_subdomain='', charset='utf-8',
strict_slashes=True, redirect_defaults=True,
converters=None, sort_parameters=False, sort_key=None,
encoding_errors='replace', host_matching=False):
self._rules = []
self._rules_by_endpoint = {}
self._remap = True
self._remap_lock = Lock() self.default_subdomain = default_subdomain
self.charset = charset
self.encoding_errors = encoding_errors
self.strict_slashes = strict_slashes
self.redirect_defaults = redirect_defaults
self.host_matching = host_matching self.converters = self.default_converters.copy()
if converters:
self.converters.update(converters) self.sort_parameters = sort_parameters
self.sort_key = sort_key for rulefactory in rules or ():
self.add(rulefactory)

3、调用app.route方法

def route(self, rule, **options):
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator

4、route方法调用add_url_rule方法

@setupmethod
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options['endpoint'] = endpoint
methods = options.pop('methods', None) # if the methods are not given and the view_func object knows its
# methods we can use that instead. If neither exists, we go with
# a tuple of only ``GET`` as default.
if methods is None:
methods = getattr(view_func, 'methods', None) or ('GET',)
if isinstance(methods, string_types):
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
methods = set(item.upper() for item in methods) # Methods that should always be added
required_methods = set(getattr(view_func, 'required_methods', ())) # starting with Flask 0.8 the view_func object can disable and
# force-enable the automatic options handling.
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None) if provide_automatic_options is None:
if 'OPTIONS' not in methods:
provide_automatic_options = True
required_methods.add('OPTIONS')
else:
provide_automatic_options = False # Add the required methods now.
methods |= required_methods rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule)

5、 add_url_rule方法rule = self.url_rule_class调用Rule方法,封装url和试图函数

add_url_rule,代码同4 ;通过url_rule_class = Rule实例化,代码同2

6、add_url_rule方法调用url_map.add(Rule)对路由的rules进行添加[Rule('/index', 函数),]

add_url_rule代码同4,调用url_map.add方法

    def add(self, rulefactory):
"""Add a new rule or factory to the map and bind it. Requires that the
rule is not bound to another map. :param rulefactory: a :class:`Rule` or :class:`RuleFactory`
"""
for rule in rulefactory.get_rules(self):
rule.bind(self)
self._rules.append(rule)
self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule)
self._remap = True

7.map类存到self.url_map中,Rule存在url_rule_class中。

同代码2.

请求流程简单源码分析

1、综述:

1.已生成路由后,由app.run执行run方法

2.run方法通过werkzeug模块执行run_simple方法

3.werkzeug模块会触发__call__方法

4.__call__方法会触发wsgi_app

5.ctx=request_context对象,触发request_context对象

6.request_context对象__init__进行实例化

--request = app.request_class(environ)

7.flask初始化通过request实例化调用Request对象,通过request实例化调用Request对象

8.Request对象通过werkzeug模块__init__进行实例化

9.存储到ctx中

10.ctx.push()调用RequestContest.push方法

2、__call__方法会触发wsgi_app

    def __call__(self, environ, start_response):
"""Shortcut for :attr:`wsgi_app`."""
return self.wsgi_app(environ, start_response)

3、ctx=request_context对象,触发request_context对象

def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
ctx.push()

4、request_context对象__init__进行实例化

def request_context(self, environ):
return RequestContext(self, environ)

--request = app.request_class(environ)

    def __init__(self, app, environ, request=None):
self.app = app
if request is None:
request = app.request_class(environ)
self.request = request
self.url_adapter = app.create_url_adapter(self.request)
self.flashes = None
self.session = None # Request contexts can be pushed multiple times and interleaved with
# other request contexts. Now only if the last level is popped we
# get rid of them. Additionally if an application context is missing
# one is created implicitly so for each level we add this information
self._implicit_app_ctx_stack = [] # indicator if the context was preserved. Next time another context
# is pushed the preserved context is popped.
self.preserved = False # remembers the exception for pop if there is one in case the context
# preservation kicks in.
self._preserved_exc = None # Functions that should be executed after the request on the response
# object. These will be called before the regular "after_request"
# functions.
self._after_request_functions = [] self.match_request()

5、flask初始化通过request实例化调用Request对象,通过request实例化调用Request对象

class Flask(_PackageBoundObject):
  request_class = Request

6、Request对象通过werkzeug模块__init__进行实例化

class Request(RequestBase):
#: The internal URL rule that matched the request. This can be
#: useful to inspect which methods are allowed for the URL from
#: a before/after handler (``request.url_rule.methods``) etc.
#:
#: .. versionadded:: 0.6
url_rule = None #: A dict of view arguments that matched the request. If an exception
#: happened when matching, this will be ``None``.
view_args = None #: If matching the URL failed, this is the exception that will be
#: raised / was raised as part of the request handling. This is
#: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
#: something similar.
routing_exception = None # Switched by the request context until 1.0 to opt in deprecated
# module functionality.
_is_old_module = False

7、.存储到ctx中

同3代码

8、ctx.push()调用RequestContest.push方法

同3代码

flask的sesstion流程

1、综述

1.RequestContext.push,调用app.open_sesstion

2.self.session调用app.open_session

3.通过session_interface变量调用到secureCookieSeeionInerface类的open_session

4.如果没有,则session_class = SecureCookieSession,open_session经过loads加密返回self.session_class(),

5.将加密session返回到self.session

6.执行视图函数

response = self.full_dispatch_request()
----调用try_trigger_before_first_request_functions
(before_first_request)
----调用preprocess_request(before_request)
----调用dispatch_request(执行试图函数)
----调用finalize_request(@fater_request)

7.finalize_request

----response = self.process_response(response)

8.process_response

----执行@fater_request函数
----self.save_session(ctx.session, response)

9.通过self.save_session调用save_session并返回SecureCookieSessionInterface.save_session(self, session, response)

10.save_session保存session,报错return null

2、RequestContext.push,调用app.open_sesstion

def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
ctx.push()
error = None
try:
try:
# 4 执行视图函数
response = self.full_dispatch_request()
except Exception as e:
# 异常处理试图报错,包含信号2345报错执行,got_request_exception信号
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
# 将处理的内容,返回给用户浏览器
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None # 9、结束
ctx.auto_pop(error)

通过self.session = self.app.open_session(self.request)调用flask.open_session方法

def open_session(self, request):
return self.session_interface.open_session(self, request)

3、self.session调用app.open_session

class RequestContext(object):
  def push(self):
  self.session = self.app.open_session(self.request)
  if self.session is None:
  self.session = self.app.make_null_session()

4、通过session_interface变量调用到secureCookieSeeionInerface类的open_session

class Flask(_PackageBoundObject):
session_interface = SecureCookieSessionInterface()

5、如果没有,则session_class = SecureCookieSession,open_session经过loads加密返回self.session_class(),

class SecureCookieSessionInterface(SessionInterface):
"""The default session interface that stores sessions in signed cookies
through the :mod:`itsdangerous` module.
"""
#: the salt that should be applied on top of the secret key for the
#: signing of cookie based sessions.
salt = 'cookie-session'
#: the hash function to use for the signature. The default is sha1
digest_method = staticmethod(hashlib.sha1)
#: the name of the itsdangerous supported key derivation. The default
#: is hmac.
key_derivation = 'hmac'
#: A python serializer for the payload. The default is a compact
#: JSON derived serializer with support for some extra Python types
#: such as datetime objects or tuples.
serializer = session_json_serializer
session_class = SecureCookieSession
  
  
  def open_session(self, app, request):
  # sission,key值
  s = self.get_signing_serializer(app)
  if s is None:
  return None
  # 如果能从cookie拿到session的话
  val = request.cookies.get(app.session_cookie_name)
  if not val:
  return self.session_class() #如果没有session,则返回一个空字典
  max_age = total_seconds(app.permanent_session_lifetime)
  try:
  data = s.loads(val, max_age=max_age) # 加密保存
  return self.session_class(data)
  except BadSignature:
  return self.session_class() # 返回session类

6、将加密session返回到self.session


class RequestContext(object):
  def push(self):
  self.session = self.app.open_session(self.request)
  if self.session is None:
  self.session = self.app.make_null_session()

7、执行视图函数

response = self.full_dispatch_request()

同代码2
----调用try_trigger_before_first_request_functions
(before_first_request)

    def full_dispatch_request(self):
"""Dispatches the request and on top of that performs request
pre and postprocessing as well as HTTP exception catching and
error handling. .. versionadded:: 0.7
"""
# 触发只执行一次的装饰器函数,@before_first_request
self.try_trigger_before_first_request_functions()

----调用preprocess_request(before_request)

----调用dispatch_request(执行试图函数)
----调用finalize_request(@fater_request)

def full_dispatch_request(self):
try:
# 执行特殊装饰器:before_request装饰的所有函数
# 如果没有返回值,rv=None;有返回值 “嘻嘻嘻”
rv = self.preprocess_request()
if rv is None:
# 触发执行视图函数,使用session
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
# 6 对返回值进行封装,执行@fater_request装饰器;session保存
return self.finalize_request(rv)

8、finalize_request

----response = self.process_response(response)

 def finalize_request(self, rv, from_error_handler=False):
''' 创建返视图返回'''
response = self.make_response(rv)
try:
'''返回值'''
response = self.process_response(response)
# 执行信号request_finished
request_finished.send(self, response=response)
except Exception:
if not from_error_handler:
raise
self.logger.exception('Request finalizing failed with an '
'error while handling an error')
return response

9、process_response

----执行@fater_request函数
----self.save_session(ctx.session, response)

def process_response(self, response):
ctx = _request_ctx_stack.top
bp = ctx.request.blueprint
funcs = ctx._after_request_functions
if bp is not None and bp in self.after_request_funcs:
funcs = chain(funcs, reversed(self.after_request_funcs[bp]))
if None in self.after_request_funcs:
funcs = chain(funcs, reversed(self.after_request_funcs[None]))
# 执行 after_request装饰器
for handler in funcs:
response = handler(response)
# 将内存中的session持久化到:数据库、....
if not self.session_interface.is_null_session(ctx.session):
self.save_session(ctx.session, response)
return response

10、通过self.save_session调用save_session并返回SecureCookieSessionInterface.save_session(self, session, response)

# Flask类
def save_session(self, session, response):
return self.session_interface.save_session(self, session, response)

11、save_session保存session,报错return null

SecureCookieSessionInterface类:
def save_session(self, app, session, response):
domain = self.get_cookie_domain(app) # 域名
path = self.get_cookie_path(app) # 路径 # Delete case. If there is no session we bail early.
# If the session was modified to be empty we remove the
# whole cookie.
if not session:
if session.modified:
response.delete_cookie(app.session_cookie_name,
domain=domain, path=path)
return # Modification case. There are upsides and downsides to
# emitting a set-cookie header each request. The behavior
# is controlled by the :meth:`should_set_cookie` method
# which performs a quick check to figure out if the cookie
# should be set or not. This is controlled by the
# SESSION_REFRESH_EACH_REQUEST config flag as well as
# the permanent flag on the session itself.
if not self.should_set_cookie(app, session):
return httponly = self.get_cookie_httponly(app)
secure = self.get_cookie_secure(app)
expires = self.get_expiration_time(app, session)
val = self.get_signing_serializer(app).dumps(dict(session)) # 加密
response.set_cookie(app.session_cookie_name, val, # 最后保存在cookie中
expires=expires, httponly=httponly,
domain=domain, path=path, secure=secure)

附录

Flask系列之源码分析(一)的更多相关文章

  1. Flask系列之源码分析(二)

    应用技术点 python之__setattr__ python之threading.local python之偏函数 flask源码上下文管理 1.综述过程 将请求对象压入栈 1.请求进入 __cal ...

  2. Spring基础系列-AOP源码分析

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...

  3. flask/app.py-add_url_rule源码分析

    之前分析route方法的时候,可以看到中间会调用add_url_rule方法,add_url_rule方法和route方法一样属于Flask这个类的. add_url_rule方法主要用来连接url规 ...

  4. Tomcat详解系列(3) - 源码分析准备和分析入口

    Tomcat - 源码分析准备和分析入口 上文我们介绍了Tomcat的架构设计,接下来我们便可以下载源码以及寻找源码入口了.@pdai 源代码下载和编译 首先是去官网下载Tomcat的源代码和二进制安 ...

  5. Flask之wtforms源码分析

    一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...

  6. Kafka源码系列之源码分析zookeeper在kafka的作用

    浪尖的kafka源码系列以kafka0.8.2.2源码为例给大家进行讲解的.纯属个人爱好,希望大家对不足之处批评指正. 一,zookeeper在分布式集群的作用 1,数据发布与订阅(配置中心) 发布与 ...

  7. Android进阶系列之源码分析Activity的启动流程

    美女镇楼,辟邪! 源码,是一个程序猿前进路上一个大的而又不得不去翻越障碍,我讨厌源码,看着一大堆.5000多行,要看完得啥时候去了啊.不过做安卓的总有这一天,自从踏上这条不归路,我就认命了.好吧,我慢 ...

  8. flask请求上下文源码分析

    一.什么是上下文 每一段程序都有很多外部变量,只有像add这种简单的函数才是没有外部变量的,一旦你的一段程序有了外部变量,这段程序就不完整了,不能独立运行,你为了使他们能运行,就要给所有的外部变量一个 ...

  9. Spring IOC 容器源码分析系列文章导读

    1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本.经过十几年的迭代,现在的 Spring 框架已经非常成熟了.Spring ...

随机推荐

  1. UGUI 的多分辨率适配

    1.Canvas的属性配置 2.Canvas Scaler的属性配置 3.根据不同的屏幕的比例动态修改缩放基准 void Start () { float standard_width = 960f; ...

  2. HDOJ 4276 The Ghost Blows Light

    题意 1. 给定一棵树, 树上节点有 value, 节点之间 travel 有 cost. 给定起始节点和最大 cost, 求解最大 value 思路 1. 寻找最短路径 a. 题目描述中有两句话, ...

  3. Android开发之--常用颜色值

    <?xml version="1.0" encoding="utf-8" ?> <resources> <color name=& ...

  4. linux复制文件到指定的文件夹

    copy命令      该命令的功能是将给出的文件或目录拷贝到另一文件或目录中,同MSDOS下的copy命令一样,功能十分强大. 语法: cp [选项] 源文件或目录 目标文件或目录 说明:该命令把指 ...

  5. iOS开发:iOS中图片与视频一次性多选 - v2m

    一.使用系统的Assets Library Framework这个是用来访问Photos程序中的图片和视频的库.其中几个类解释如下 ALAsset ->包含一个图片或视频的各种信息 ALAsse ...

  6. PHP之命名空间

    前面的话 从广义上来说,命名空间是一种封装事物的方法.在很多地方都可以见到这种抽象概念.例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色.这个原理应用到程序设计 ...

  7. JavaWeb温习之防止表单重复提交

    表单重复提交主要有以下三种情况: 1. 在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交 2. 表单提交后用户点击[刷新]按钮导致表单重复提交 3. 用户提交表单后,点击浏览器的 ...

  8. hdu 5318 The Goddess Of The Moon

    The Goddess Of The Moon Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  9. Array.prototype.forEach数组遍历

    forEach是Array新方法中最基本的一个,就是遍历,循环.先看以前是怎么遍历数组的 常用遍历 var arr = [1,2,3,4,5]; for(var i = 0; i < arr.l ...

  10. node中的对象

    1. class的概念 定义一个class,属性都是private,方法都是public. Hello.js: 使用class index.js: 2. 单例类 使用exports而不是module. ...