-
Notifications
You must be signed in to change notification settings - Fork 0
/
python.txt
360 lines (292 loc) · 12.3 KB
/
python.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
三次握手:
1、客户端->服务端:SYN=1,seq=i(客户端进入SYN_SEND)
2、服务端->客户端:SYN=1,ACK=1,seq=j,ack=i+1(服务端进入SYN_RECV)
3、客户端->服务端,ACK=1,ack=j+1(双方进入ESTABLISHED状态)
第三次握手的目的:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
即第一次握手的动作,由于网络延迟,会滞后达到客户端,如果没有第三次握手,那么服务端就认为建立连接,server会一直等待,浪费资源。
因为client不认为那是新的连接请求,所以加了第三次握手。
四次挥手:
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,
所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,
因此,己方ACK和FIN一般都会分开发送。
①:with语句原理
上下文管理协议:包含__enter__()和__exit__()方法
上下文管理器,支持上下文管理协议的对象,支持运行时上下文,
with语句格式:
with context_expression [as target(s)]
with-body
context_expression 返回一个上下文管理器对象,该对象并不赋值给 as 子句中的 target(s),而是上下文管理器的 __enter__() 方法的返回值赋值给 target(s)
with-body语句执行之前会调用上下文管理器的 __enter__() 方法,执行完语句体之后会执行 __exit__() 方法。
②:多线程实现以及对变量访问的互斥加锁
import threading
lock = threading.Lock()
num = 1 //全局变量
def f1():
global num
lock.acquire()//加锁
for i in range(1,1000000):
num = num + 1
num = num - 1
lock.release()//解锁
def f2():
global num
lock.acquire()//加锁
for i in range(1,1000000):
num = num + 1
num = num - 1
lock.release()//解锁
if __name__ == '__main__':
t1 = threading.Thread(target=f1)
t2 = threading.Thread(target=f2)
t1.start()
t2.start()
t1.join()
t2.join()
print num
③:__new__和__init__函数的区别,使用__new__函数来实现单例模式(Singleton)
创建一个新实例时调用__new__,初始化一个实例时用__init__,这是它们最本质的区别。
new方法会返回所构造的对象,init则不会.
new函数必须以cls作为第一个参数,而init则以self作为其第一个参数.
__metaclass__=type
class Singleton(object):
def __new__(cls):
print "__new__ called"
if not hasattr(cls,'_instance'):
cls._instance = super(Singleton,cls).__new__(cls)
return cls._instance
def __init__(self):
print "__init__ called"
__call__的作用
④:python回收机制(GC:garbage collection)及其解释,引用计数为主,标记-清除、分代收集为辅
1、引用计数:当一个对象有新的引用时,它的ob_refcnt就会+1,实时性好,维护引用计数器消耗资源
2、标记-清除机制:基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,
遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。
3、分代回收:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,
垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。
⑤:函数式编程思想,map和reduce等
把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
1、map(function, sequence):接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
例如:
def f(x):
return x*x
list_map = map(f,[1,2,3,4,5])
2、reduce,reduce(function, sequence[, initial]) -> value
reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,
reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
例如:
def add(x,y):
return x+y
result = reduce(add, [1, 3, 5, 7, 9])
⑥:语法糖装饰器的作用,用例子实现讲解,使用情况,装饰器的实质,用于性能测试,记录日志等
装饰器其实就是一个闭包,把一个函数当做另一个函数的参数传入,然后返回一个替代版函数,如下:
import time
def decorator(some_func):
def wrapper(*args, **kw):
start_time = time.time()
some_func(*args, **kw)
end_time = time.time()
print (end_time - start_time)
return wrapper
def func():
for i in range(1,1000000):
pass
func = decorator(func)
func()
我们可以认为对函数变量func进行了重新的赋值,是原先func函数的的一个装饰版本,一个加强版本。(对func函数进行计时)
使用语法糖规则可以达到代码简化的功能,不用对foo重新赋值语句,例子如下:
@decorator
def func():
for i in range(1,1000000):
pass
⑦:Python中的@property有什么作用?如何实现成员变量的只读属性?
@property装饰器就是负责把一个方法变成属性调用,通常用在属性的get方法和set方法,
通过设置@property可以实现实例成员变量的直接访问,又保留了参数的检查。
另外通过设置get方法而不定义set方法可以实现成员变量的只读属性。
例如:
class Student(object):
def __init__(self):
self._score = 60
@property
def score(self):
return self._score
@score.setter
def score(self,value):
if not isinstance(value,int):
raise ValueError('score must be an integer')
if value<0 or value >100
raise ValueError('score must between 0~100')
self._score = value
函数递归调用,斐波那契数列的实现,用代码
手写一个函数,传入一个文件路径,函数实现输出当前路径所有文件的功能
Django相关:
创建项目:django-admin startproject project_name
创建应用:python manage.py startapp app_name
启动网站:python manage.py runserver IP:PORT(如果IP和PORT不填,默认启动http://127.0.0.1:8000)
①:python manage.py runserver
②:python manage.py runserver 192.168.163.137:8000
Django创建项目后,项目文件夹下的组成部分
首先创建项目:django-admin startproject mblog(项目名),会生成mblog目录
进入mblog目录后,在创建一个应用:python manage.py startapp mysite(应用名)
整个项目目录结构如下:
mblog:
mblog(文件夹):
__init__.py
wsgi.py
urls.py
setting.py
template(不自动生成,可人工创建该文件夹)
static(不自动生成,可人工创建该文件夹)
image(文件夹,用于存放项目image文件)
css(文件夹,用于存放项目.css文件)
js(文件夹,用于存放项目.js文件)
views.py(不自动生成,可人工创建)
manage.py(文件)
misite(文件夹):
__init__.py
tests.py
admin.py
models.py
views.py
migrations(文件夹)
template(不自动生成,可人工创建)
文件详细说明:
①:mblog文件夹下的文件
__init__.py: 一个空文件,作用是这个目录可以被当作模块(包)使用
wsgi.py:项目与WSGI兼容的Web服务器入口
urls.py:项目的URL配置文件(网址与函数的对应)
settings.py:项目的整体配置文件,可配置数据库,模板,中间件,静态文件,应用,语言,时区等
②:manage.py文件:
manage.py是用来管理网站配置的文件,是一个接受命令行指令的工具程序
③:misite文件夹下的文件
__init__.py: 一个空文件,作用是这个目录可以被当作模块(包)使用
tests.py:没什么用
admin.py:数据库管理界面配置文件,将自己创建的模型类注册到管理界面
models.py:模型文件,在此文件中定义数据库表模型类,每张table可定义成一个class
views.py:视图函数文件,在此文件中定义与url正则匹配的视图函数
migrations:是一个数据库目录,当对数据库增删改除操作时,会有相应的文件生成在此目录
除此之外:
①:模板文件
template文件夹用于存放模板文件,即html文件,可分别在mblog和mysite目录下创建各自的template,
mblog目录下的templates用于存放base.html, footer.html, header.html
mysite目录下的templates用于存放适用于本app的html文件,分别{% extends base.html %}即可
也可以将所有的html文件统一放在mblog下的templates文件夹中,进行统一管理
②:静态文件
静态文件包括image、css、js文件等,可在项目目录下创建static文件夹,然后在static文件夹下
分别创建image、css、js文件夹,分别存储.img .css .js文件
③:views.py和urls.py
在项目目录和应用目录下都可以创建views.py和urls.py
对于urls.py,里面使用正则表达式,将相关的url和views.py中的视图函数进行匹配,
可以在项目中使用命名空间在urls.py文件中include各个应用下的urls.py,对urlpatterns进行统一管理
例如:
from mysite import urls(项目urls.py导入应用模块的urls.py)
urlpatterns = [
url(r'^', include(urls), namespace='mysite'),
url(r'^admin', include(admin.site.urls)),
]
对MTV的理解:
MTV即Model、Template、View,对应于MVC中的Model、View、Control
Model->Model:M指的是Model,模型层,实现对数据库定义和存储
Template->View:T指的是Template,视图层,实现对模型层中数据的读写操作
View->Control:V指的是View,控制层(视图函数),在视图函数中对数据进行获取,将数据传给Template进行渲染
模型层(Model)操作:
django项目默认数据库存储后端是SQLite,如果要修改后端存储,改成mysql,就要安装mysql并进行相应的配置。
例如在settings.py文件中配置数据库的存储后端名称、数据库主机ip、用户名、密码等
在models.py中定义好一个模型类后,如:
from django.db import models(导入模型类)
from django.contrib import auth
创建模型类
class User(models.Model):
name = models.CharField(max_length=20, null=False)
email = models.EmailField()
password = models.CharField(max_length=20, null=False)
enabled = models.BooleanField(default=False)
设计完模型类后,要同步数据库,执行以下两条命令:
python manage.py makemigrations app_name(创建和更新数据库中间文件,migrations目录下的东西)
python manage.py migrate(对数据库进行创建和更新)
通过admin.py将模型类注册到数据库管理界面:
例如:
from mysite.models import Post,Mood,User,Profile(导入定义的类)
from django.contrib import admin
修改此类显示界面
class PostAdmin(admin.ModelAdmin):
list_display = ('nickname', 'message', 'enabled', 'pub_time')
ordering = ('-pub_time',)
admin.site.register(Mood)
admin.site.register(Post, PostAdmin)
admin.site.register(User)
admin.site.register(Profile)
表单Form:
可在mysite目录下创建forms.py文件,用于创建表单类
例如:
from django import forms(导入表单模块)
from mysite import models
①:创建表单类
class ContactForm(forms.Form):
CITY = [
['TP', 'Taipei'],
['TY', 'Taoyuang'],
['TC', 'Taichung'],
['TN', 'Tainan'],
['KS', 'Kaohsiung'],
['NA', 'Others']
]
user_name = forms.CharField(label='您的姓名', max_length=50, initial='李大仁')
user_city = forms.ChoiceField(label='居住城市', choices=CITY)
user_school = forms.BooleanField(label='是否在学', required=False)
user_email = forms.EmailField(label='电子邮件')
user_message = forms.CharField(label='您的意见', widget=forms.Textarea)
①:创建模型表单类,将表单直接与模型相关联
class PostForm(forms.ModelForm):
class Meta:
model = models.Post
fields = ['mood', 'nickname', 'message', 'del_pass']
def __init__(self, *args, **kwargs):
super(PostForm, self).__init__(*args, **kwargs)
self.fields['mood'].label = '现在的心情'
self.fields['nickname'].label = '您的昵称'
self.fields['message'].label = '心情留言'
self.fields['del_pass'].label = '设置密码'
models.Model中常用的数据字段:
IntegerField 整数字段
FloatField 浮点数字段
BooleanField 布尔值
CharFiled(max_length) 字符串
DateField(auto_now) 日期格式,对应datetime.date
DateTimeField 日期格式,对应datetime.datetime
EmailField 电子邮件格式字段
URLField(max_length) 和CharField一样,用于记录完整的URL
TextField 长文字格式,一般用于在HTML窗体的Textarea输入项目中
数据的查询与编辑,常用函数与修饰词
create(),创建一行记录
save(),保存
all(),返回所有QuerySet,users = User.object.all()
filter(),返回符合指定条件的QuerySet
order_by(),串接到QuerySet之后,针对某一指定的字段进行排序
exclude(),返回不符合指定条件的QuerySet
get(),获取指定符合条件的 唯一 元素,如果找不到或有一个以上的条件符合,产生异常,user = User.objects.get()
first()/last(),获取第一个和最后一个, user = User.objects.first()/user = User.objects.last()
exists(),用来检查是否存在某指令条件的记录,通常附加载filter()后面
update()
delete(),删除指定记录
contains/icontains,如SQL语句中的LIKE和ILIKE
in,提供一个列表,只要符合列表中的任何一个值均可
gt/gte/lt/lte, 大于/大于等于/小于/小于等于
iexact,不区分大小写的条件设置
例如,有一个Product模型类:
#####################################
filter()条件格式 :
filter(模型类属性名__条件名=值)
#####################################
Product.objects.all()
Product.objects.filter(qty=0)
Product.objects.exclude(qty=0)
Product.objects.filter(price__lte=500)
Product.objects.filter(name__icontains='sony')
Product.objects.filter(qty__in=[1,2])
Product.objects.filter(name__contains='SONY').exists()