from wsgiref.simple_server import make_server import falcon
classThingsResource: defon_get(self, req, resp): """Handles GET requests""" resp.status = falcon.HTTP_200 # This is the default status resp.content_type = falcon.MEDIA_TEXT # Default is JSON, so override resp.text = ('nTwo things awe me most, the starry sky ' 'above me and the moral law within me.n' 'n' ' ~ Immanuel Kantnn')
app = falcon.App()
things = ThingsResource()
app.add_route('/things', things)
if __name__ == '__main__': with make_server('', 8000, app) as httpd: print('Serving on port 8000...')
还有一个问题可能你们不知道,Sanic 在创建之初目标就是创建一个可以用于生产环境的 Web 框架。可能有些框架会明确的说明框架中自带的 Run 方法仅用于测试环境,不要使用自带的 Run 方法用于部署环境。但是 Sanic 所创建的不止是一个用于测试环境的应用,更是可以直接用在生产环境中的应用。省去了使用 unicorn 等部署的烦恼!
def get_source(): """获取数据源""" return def extract_(val): """匹配关键数据""" return def fetch(val): """发出网络请求""" return def trim(val): """修剪数据""" return def extract(file): """提取目标数据""" source = get_source() content = extract_(source) text = trim(fetch(content)) return text if __name__ == "__main__": text = extract(FILE) print(text)
把原来放在一个函数中实现的多个步骤拆分成为多个更小的函数,每个函数只做一件事。当数据源发生变化时,只需要改动 get_source 相关的代码即可;如果网络请求返回的数据不符合最终要求,我们可以在 trim 函数中对它进行修剪。这样一来,代码应对变化的能力提高了许多,整个流程也变得更清晰易懂。改动前后的变化如下图所示:
开放封闭原则中的开放指的是对扩展开放,封闭指的是对修改封闭。需求总是变化的,业务方这个月让你把数据存储到 MySQL 数据库中,下个月就有可能让你导出到 Excel 表格里,这时候你就得改代码了。这个场景和上面的单一职责原则很相似,同样面临代码改动,单一职责原则示例主要表达的是通过解耦降低改动的影响,这里主要表达的是通过对扩展开放、对修改封闭提高程序应对变化的能力和提高程序稳定性。
import abc class Car: def move(self): pass def engine(self): pass class KateCar(Car): def move(self): pass def engine(self): pass class FluentCar(Car): def move(self): pass def engine(self): pass
这里的 Car 作为父类,拥有 move 和 engine 2 个重要属性,这时候如果需要给汽车涂装颜色,那么就要新增一个 color 属性,3 个类都要增加。如果使用合成复用的方式,可以这么写:
class Color: pass class KateCar: color = Color() def move(self): pass def engine(self): pass class FluentCar: color = Color() def move(self): pass def engine(self): pass
Traceback (most recent calllast):
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/manage.py", line 22, in <module>
main()
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/manage.py", line 18, inmain
execute_from_command_line(sys.argv)
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 345, inexecute
settings.INSTALLED_APPS
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 82, in __getattr__
self._setup(name)
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 69, in _setup
self._wrapped = Settings(settings_module)
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 170, in __init__
mod = importlib.import_module(self.SETTINGS_MODULE)
File"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File"<frozen importlib._bootstrap>", line 1006, in _gcd_import
File"<frozen importlib._bootstrap>", line 983, in _find_and_load
File"<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File"<frozen importlib._bootstrap>", line 677, in _load_unlocked
File"<frozen importlib._bootstrap_external>", line 728, in exec_module
File"<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File"/Users/qiguan/Documents/develop_files/python_files/SSO1/SSO1/settings.py", line 57, in <module>
'DIRS': [os.path.join(BASE_DIR, 'templates')]
NameError: name'os'isnot defined
"""SSO1 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""from django.contrib import admin
from django.urls import path
from . import view
urlpatterns = [
path('admin/', admin.site.urls),
path('login/',view.login),
path('logout/',view.logout),
]
# 推荐写法,代码耗时:0.33秒 class DemoClass: def __init__(self, value: int): self.value = value # 避免不必要的属性访问器
def main(): size = 1000000 for i in range(size): demo_instance = DemoClass(size) value = demo_instance.value demo_instance.value = i
main()
4. 避免数据复制
4.1 避免无意义的数据复制
# 不推荐写法,代码耗时:6.5秒 def main(): size = 10000 for _ in range(size): value = range(size) value_list = [x for x in value] square_list = [x * x for x in value_list]
main()
上面的代码中value_list完全没有必要,这会创建不必要的数据结构或复制。
# 推荐写法,代码耗时:4.8秒 def main(): size = 10000 for _ in range(size): value = range(size) square_list = [x * x for x in value] # 避免无意义的复制
def main(): string_list = list(string.ascii_letters * 100) for _ in range(10000): result = concatString(string_list)
main()
5. 利用if条件的短路特性
# 不推荐写法,代码耗时:0.05秒 from typing import List
def concatString(string_list: List[str]) -> str: abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'} abbr_count = 0 result = '' for str_i in string_list: if str_i in abbreviations: result += str_i return result
def main(): for _ in range(10000): string_list = ['Mr.', 'Hat', 'is', 'Chasing', 'the', 'black', 'cat', '.'] result = concatString(string_list)
main()
if 条件的短路特性是指对if a and b这样的语句, 当a为False时将直接返回,不再计算b;对于if a or b这样的语句,当a为True时将直接返回,不再计算b。因此, 为了节约运行时间,对于or语句,应该将值为True可能性比较高的变量写在or前,而and应该推后。
# 推荐写法,代码耗时:0.03秒 from typing import List
def concatString(string_list: List[str]) -> str: abbreviations = {'cf.', 'e.g.', 'ex.', 'etc.', 'flg.', 'i.e.', 'Mr.', 'vs.'} abbr_count = 0 result = '' for str_i in string_list: if str_i[-1] == '.' and str_i in abbreviations: # 利用 if 条件的短路特性 result += str_i return result
def main(): for _ in range(10000): string_list = ['Mr.', 'Hat', 'is', 'Chasing', 'the', 'black', 'cat', '.'] result = concatString(string_list)
main()
6. 循环优化
6.1 用for循环代替while循环
# 不推荐写法。代码耗时:6.7秒 def computeSum(size: int) -> int: sum_ = 0 i = 0 while i < size: sum_ += i i += 1 return sum_
def main(): size = 10000 for _ in range(size): sum_ = computeSum(size)
main()
Python 的for循环比while循环快不少。
# 推荐写法。代码耗时:4.3秒 def computeSum(size: int) -> int: sum_ = 0 for i in range(size): # for 循环代替 while 循环 sum_ += i return sum_
def main(): size = 10000 for _ in range(size): sum_ = computeSum(size)
main()
6.2 使用隐式for循环代替显式for循环
针对上面的例子,更进一步可以用隐式for循环来替代显式for循环
# 推荐写法。代码耗时:1.7秒 def computeSum(size: int) -> int: return sum(range(size)) # 隐式 for 循环代替显式 for 循环
def main(): size = 10000 for _ in range(size): sum = computeSum(size)
main()
6.3 减少内层for循环的计算
# 不推荐写法。代码耗时:12.8秒 import math
def main(): size = 10000 sqrt = math.sqrt for x in range(size): for y in range(size): z = sqrt(x) + sqrt(y)
main()
上面的代码中sqrt(x)位于内侧for循环, 每次训练过程中都会重新计算一次,增加了时间开销。
# 推荐写法。代码耗时:7.0秒 import math
def main(): size = 10000 sqrt = math.sqrt for x in range(size): sqrt_x = sqrt(x) # 减少内层 for 循环的计算 for y in range(size): z = sqrt_x + sqrt(y)