面向对象程序设计(Object-oriented programming,OOP)有三大特征 ——封装、继承、多态
。
封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
关键字:public, protected, private。不写默认为 private。
1.public 成员:可以被任意实体访问。
2.protected 成员:只允许被子类及本类的成员函数访问。
3.private 成员:只允许被本类的成员函数、友元类或友元函数访问。
继承:基类(父类)——> 派生类(子类)
多态:即多种状态(形态)。简单来说,我们可以将多态定义为消息以多种形式显示的能力。多态是以封装和继承为基础的。
C++ 多态分类及实现:
1.重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载
2.子类型多态(Subtype Polymorphism,运行期):虚函数
3.参数多态性(Parametric Polymorphism,编译期):类模板、函数模板
4.强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换
我们创建列表的时候,受到内存限制,容量肯定是有限的,而且不可能全部给他一次枚举出来。Python常用的列表生成式有一个致命的缺点就是定义即生成,非常的浪费空间和效率。
如果列表元素可以按照某种算法推算出来,那我们可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator
。
要创建一个generator,最简单的方法是改造列表生成式:
a = [x * x for x in range(10)]
print(a)
b = (x * x for x in range(10))
print(b)
print(list(b))
for i in b:
print(i)
--------结果如下--------------
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x10557da50>
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
0
1
4
9
16
25
36
49
64
81
还有一个方法是生成器函数,通过def定义,然后使用yield来支持迭代器协议,比迭代器写起来更简单。
def spam():
yield"first"
yield"second"
yield"third"
for x in spam():
print(x)
-------结果如下---------
first
second
third
进行函数调用的时候,返回一个生成器对象。在使用next()调用的时候,遇到yield就返回,记录此时的函数调用位置,下次调用next()时,从断点处开始。
我们完全可以像使用迭代器一样使用 generator ,当然除了定义。定义一个迭代器,需要分别实现 iter() 方法和 next() 方法,但 generator 只需要一个小小的yield。
generator还有 send() 和 close() 方法,都是只能在next()调用之后,生成器处于挂起状态时才能使用的。
python是支持协程的,也就是微线程,就是通过generator来实现的。配合generator我们可以自定义函数的调用层次关系从而自己来调度线程。
装饰器允许通过将现有函数传递给装饰器,从而向现有函数添加一些额外的功能
,该装饰器将执行现有函数的功能和添加的额外功能。
装饰器本质上还是一个函数,它可以让已有的函数不做任何改动的情况下增加功能。
接下来我们使用一些例子来具体说明装饰器的作用:
如果我们不使用装饰器,我们通常会这样来实现在函数执行前插入日志:
def foo():
print('i am foo')
def foo():
print('foo is running')
print('i am foo')
虽然这样写是满足了需求,但是改动了原有的代码,如果有其他的函数也需要插入日志的话,就需要改写所有的函数,这样不能复用代码。
我们可以进行如下改写:
import logging
def use_log(func):
logging.warning("%s is running" % func.__name__)
func()
def bar():
print('i am bar')
use_log(bar) #将函数作为参数传入
-------------运行结果如下--------------
WARNING:root:bar is running
i am bar
其中,use_log函数就是装饰器,它把我们真正想要执行的函数bar()封装在里面,返回一个封装了加入代码的新函数,看起来就像是bar()被装饰了一样。
但是这样写还是不够隐式,我们可以通过@语法糖来起到bar = use_log(bar)的作用。
import logging
def use_log(func):
def wrapper(*args, **kwargs):
logging.warning('%s is running' % func.__name__)
return func(*args, **kwargs)
return wrapper
@use_log
def bar():
print('I am bar')
@use_log
def haha():
print('I am haha')
bar()
haha()
------------结果如下------------
WARNING:root:bar is running
I am bar
WARNING:root:haha is running
I am haha
TCP/IP四层模型:
1.应用层
:负责各种不同应用之间的协议,如文件传输协议(FTP),远程登陆协议(Telnet),电子邮件协议(SMTP),网络文件服务协议(NFS),网络管理协议(SNMP)等。
2.传输层
:负责可靠传输的TCP协议、高效传输的UDP协议。
3.网络层
:负责寻址(准确找到对方设备)的IP,ICMP,ARP,RARP等协议。
4.数据链路层
:负责将数字信号在物理通道(网线)中准确传输。
四层模型逻辑:
发送端是由上至下,把上层来的数据在头部加上各层协议的数据(部首)再下发给下层。
接受端则由下而上,把从下层接收到的数据进行解密和去掉头部的部首后再发送给上层。
层层加密和解密后,应用层最终拿到了需要的数据。
OSI七层模型的相关概念