05-python基础

1、python是什么?

解释性语言、高级语言、开源、简洁、方便、容易扩展

2、可变类型与不可变类型

可变类型:list、dict、可变集合set
不可变类型:数字,str,tuple元组,frozenset (不可变的类型都可以被hash哈希)

内存中的那块内容(value)是否可变

3、深浅copy

浅拷贝。增加一个指针,指向所复制的对象,共用一块内存
深拷贝。增加一个指针,并且开辟了新的内存,这个增加的指针指向这个新的内存
简单地说,浅拷贝只拷贝一层(如果有嵌套),深拷贝拷贝所有层。

4、*args与**kwargs

*args:位置参数,元组,('alex',18)
**kwargs:关键字参数,字典, {'name'='alex','age'=18} 关键字参数一定要放在最后面

5、闭包

内部函数对外部函数,作用域里变量(非全局变量),的引用,则称内部函数为闭包。

闭包的意义:返回函数对象+一层作用域
该函数无论在何处调用,优先使用,自己外层包裹的作用域

6、装饰器

调用装饰器其实是一个闭包函数,
不修改函数的代码与修饰方式,为其他函数添加附加功能
比如:插入日志、性能测试、事物处理、缓存、权限验证等

# 装饰器
import time
def login(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print("fun 执行时间",end_time-start_time)
    return inner

@login
def test():
    pass    

7、生成器

延迟操作,需要的时候才产生结果,而不是立即产生结果
在每次调用next()的时候执行,遇到yield语句返回

创建生成器的两种方式:

  1. li = [i for i in range(100)]
  2. yield方法

8、range-and-xrange

py2:
    range() 生成的是列表
    xrange() 生成的是一个生成器 
py3:
    range() 就是一个生成器
    xrange() 没了

9、迭代器

不是一次性把数据加载到内存,而是被next()函数调用,不断返回下一个数据

可for循环的数据类型:集合数据类型+生成器
list,tuple,dict,set,str + generator

10、经典类、新式类

经典类:深度优先,python2中
新式类:广度优先,Python3中

11、继承、多态、封装

  1. 继承:类与类之间关系,解决代码重用问题 。重用父类的属性与方法

  2. 多态:同一类事物多种形态 。一个接口,多种形态
    不应关注对象的类型本身,而是它如何使用的
    鸭子类型:如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子

  3. 封装:私有化的属性,私有化的方法,封装起来,外部无法调用
    双下划线__foo

12、classmethod,staticmethod,property

  1. property:特性 (统一访问 原则)
    把类的方法转换为属性,直接 alex.bmi 调用
@property
def bmi(self):
    return self.weight / (self.height ** 2)
  1. staticmethod 静态方法 (普通函数 ) 绑定到对象上
    类内的函数实例化---> 普通函数 。 (类和对象都可以使用)
        @classmethod
        def from_conf(cls):
            obj = settings.name,
            return obj
  1. classmethod 类方法 (def foo(cls)) 绑定到类上
    将cls 类本身当做参数传入,直接用类来调用函数,而不用借助类实例
    优雅地实现某个类的实例的构造

13、 new, __init__区别

创建一个新实例时调用__new__ , __new__在 init__之前被调用
初始化一个实例时调用__init

14、单例模式

单例模式设计的类,每次只能实例化1个对象
方式2: new _instance

class Single(object):
    _instance = None
    def __new__(cls,*args,**kwargs):
        if not _instance:
            cls._instance = super(Single,cls).__new__(cls,*args,**kwargs)
        return cls._instance

15、反射

以“字符串”形式,操作对象的相关属性或方法。
hasattr, getattr, setattr, delattr

ret = getattr(obj,'get_file')()       # 反射  obj是实例对象,name是方法 

16、GIL

GIL:全局解释器锁(cpython解释器), 同一时刻,在cpu只能有一个线程执行
C语言解决多线程下的GIL问题

17、协程

协程:轻量级的线程,用户程序自己控制调度的

单线程下的并发, 遇到I/O阻塞,多个任务,自动切换

gevent模块实现

import gevent

def eat():
    gevent.sleep(2)   # 遇到阻塞会自动切换任务

def play():
    gevent.sleep(3)

g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join()
g2.join()

18、进程,线程 (I/O密集型)

from multiprocessing import Process
from threading import Thread  # 子线程

def task(name):
    print(name)

p = Process(target=task,args=('子进程',))
p = Thread(target=task,args=('子线程',))  
p.start()   # 给os发个信号
p.join()    # 父进程等待子进程执行完,才执行 

19、僵尸进程,孤儿进程,守护进程

  1. 僵尸进程
    子进程退出,父进程没有回收子进程,子进程的进程描述符仍然保存在系统中。
  2. 孤儿进程
    父进程退出,子进程还在运行。孤儿进程将被init进程(pid=1)回收
  3. 守护进程
    如果子进程的任务在主进程任务结束后就没有存在的必要了,那么该子进程应该在开启前就被设置成守护进程。

20、进程/线程 间同步方式

  1. 临界区。相当于保护区域
  2. 互斥量。加锁控制
from threading import Thread,Lock,RLock
mutexA=Lock()
mutexB=Lock()

mutexA=mutexB=RLock() 
#一个线程拿到锁,counter加1,该线程内又碰到加锁的情况,则counter继续加1,
# 这期间所有其他线程都只能等待,等待该线程释放所有锁,即counter递减到0为止

mutexA.acquire()
mutexA.release()
  1. 信号量。PV操作--改变信号量的值 S+1+1+1-1-1-1
    信号量也是一把锁,可以指定信号量为5,
    互斥锁同一时间只能有一个任务抢到锁去执行
    信号量同一时间可以有5个任务拿到锁去执行
解析
Semaphore管理一个内置的计数器,
每当调用acquire()时内置计数器-1;
调用release() 时内置计数器+1;
计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。
  1. 事件Event。相当于通知操作
from threading import Thread, Event
import time
event = Event()
def conn():
    event.wait()        # 默认是False阻塞中, 等变为True 程序放行

def check():
    time.sleep(5)       
    event.set()         # Event对象 的信号标志设置未True

t1 = Thread(target=conn)
t2 = Thread(target=check)
t1.start()
t2.start()

21、整数对象池

  1. 小整数对象池。对小整数的定义是 [-5, 257) 这些整数对象是提前建立好的,不会被垃圾回收
  2. 大整数对象池。不共用内存,引用计数为0,销毁

22、python垃圾回收机制 Garbage collection(GC)

  1. 引用计数为主。当引用计数为0,该对象的生命就结束了
  2. 标记-清除。解决循环引用的问题
  3. 隔代回收为辅。内存块根据存活时间分为'代',gc的频率随着'代'的存活时间的增大而减小
    https://www.cnblogs.com/pinganzi/p/6646742.html http://python.jobbole.com/82061/

23、网络编程

# 服务端
import socket
from threading import Thread

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # 端口占用
server.bind(('127.0.0.1', 9994))
server.listen(5)

while True:
    conn, addr = server.accept()

    t = Thread(target=handle,args=(conn,))
    t.start()

    conn.close()
server.close()

def handle(conn):
    data = conn.recv(1024)
    conn.send(data)
# 客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 9994))

while True:
    data = input('>>>').strip()
    client.send(data.encode('utf-8'))

    ret = client.recv(1024)
    print('from server:', ret.decode('gbk'))   # windows gbk编码

client.close()
posted @ 2018-10-08 16:58  venicid  阅读(164)  评论(0编辑  收藏  举报