文章目录
python核心知识点
Python的几种实现
Cpython,使用c语言实现
Jython 使用jvm虚拟机实现
ironPython 使用.net平台实现
pypy 采用jit编译技术实现,比Cpython更快,直接生成机器码
python2和python3的区别
打印函数:
Python 2:使用print语句,例如 print "Hello, World!"。
Python 3:引入了print()函数,例如 print("Hello, World!")。
整数除法:
Python 2:整数除法会自动截断结果,例如 3 / 2 结果为 1。
Python 3:整数除法会得到精确的浮点数结果,例如 3 / 2 结果为 1.5。
字符串上的区别:
Python 2:str字面量默认是字节序列,其在内存中的编码方式主要取决于源文件的编码方式(# -*- coding: utf-8 -*-)和python解释器内部的编码方式(sys.getdefaultencoding())或系统环境
Python 3:str字面量默认是unicode字符串,其在内存中的编码方式是utf16或utf32。使用bytes表示字节序列。
xrange()函数:
Python 2:使用xrange()生成一个迭代器,适用于大数据集。
Python 3:取消了xrange(),只保留了range()函数。
字典的.keys(), .values(), 和 .items()方法:
Python 2:这些方法返回列表。
Python 3:这些方法返回视图对象,需要通过list()函数转换为列表。(视图对象的特点:动态更新、集合操作)
异常语法:
Python 2:except语句后可以直接使用元组捕获多个异常,例如 except (ValueError, KeyError):。
Python 3:必须使用as关键字,例如 except (ValueError, KeyError) as e:。
比较运算符:
Python 2:<, <=, >, 和 >= 运算符在不同类型的对象之间可以进行比较。 例子:(2,3) > [3,4]
Python 3:这些运算符只允许同类型的对象之间进行比较。
迭代器和zip()函数:
Python 3中的zip()函数返回一个迭代器,而不是列表。
python3的新特性:
类型注解typing,f字符串,dataclass装饰器(可以省略__init__,repr()方法)
from dataclasses import dataclass
@dataclass
class Armor:
armor: float
description: str
level: int = 1
基础库运用
os sys math random string re struct base64 hashlib datetime
collections itertools functools contextlib urllib pillow requests
os
print("# ############################### os ################################")
import os
dirname = os.path.dirname(__file__)
realpath = os.path.realpath('../basic_lib')
print os.path.join(realpath, 'apps') # /home/jianchao/code/interview/basic/apps
sys
print("# ############################### sys ################################")
import sys
# argv
print sys.argv # 命令行参数 list
# byteorder
print sys.byteorder # 本机字节序 string
# exc_info
try:
1 / 0
except Exception, e:
print sys.exc_info() # 当前异常信息,根据堆栈框架向上获取
print sys.exc_type
print sys.exc_value
print sys.exc_traceback
# getdefaultencoding
print sys.getdefaultencoding() # 返回当前编码方式
print sys.modules # 导入的模块 dict
print sys.path # 导入模块时python解释器的搜索路径 list
import sys
reload(sys) # python2.5把setdefaultcoding删除了,需要重新加载
sys.setdefaultencoding("utf8") # 设置python2的默认编码
math
print "# ############################### math ################################"
import math
print math.pow(1, 2) # 幂运算
print math.pi
print math.log(1, 100) # 对数
print math.cos(1) # 余弦
print math.sin(1) # 正弦
print math.tan(1) # 正切
print math.sqrt(4) # 开根
print math.fabs(-10) # 求绝对值 abs()
random
print "# ############################### random ################################"
import random,string
random.seed(2) # 随机数种子
print random.random()
print(random.randint(1, 10)) # 产生 1 到 10 的一个整数型随机数
print(random.random()) # 产生 0 到 1 之间的随机浮点数
print(random.uniform(1.1, 5.4)) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print(random.choice(string.ascii_letters + string.digits, length=24)) # 从序列中随机选取指定长度的元素
print(random.randrange(1, 100, 2)) # 生成从1到100的间隔为2的随机整数
print random.sample('zyxwvutsrqponmlkjihgfedcba', 5) # 多个字符中生成指定数量的随机字符 (python3已删除)
s = [1, 2, 3, 4]
random.shuffle(s) # 打乱顺序
print s
# random生成的随机数是伪随机数,采用线性同余,平方取中的方法来实现
string
print "# ############################### string ################################"
import string
print string.ascii_letters # 大小写字母
print string.ascii_lowercase # 小写字母
print string.ascii_uppercase # 大写字母
print string.digits # 十进制数
from string import Template
t = Template("$author $book")
print t.substitute(author='a', book='c')
# python3 f字符串
name="bidden joe";age=20;
teststr = f"He name is {name},his age is {age}"
re
print "# ############################### re ################################"
import re
pattern = re.compile("(\w+) (?P<name>\d+)") # 正则模板
print pattern.search("fdsa 123213").group() # 'fdsa 123213'
print pattern.search("123 fdsa 12").groupdict() # {'name': '12'}
print re.match("\d*", "1312312").group() # '1312312'
print re.search("\d+", "fds1afd").group() # '1'
print re.search("(?P<v>\d+)", "http://test.com?v=123").groupdict() # {"v": "123"}
print re.split("\d", "fds1af1ds") # ['fds', 'af', 'ds']
print re.findall("\d", "fds1af1dsa") # ['1', '1']
print re.sub("\d", "|", "1fds2a") # '|fds|a'
struct
print "# ############################### struct ################################"
"""
解释:将 Python 的数据类型(如整数、浮点数、字符串等)打包(pack)成字节串,以便在二进制文件或网络数据流中传输或存储
Character Byte order Size Alignment
@(默认) 本机 本机 本机,凑够4字节
= 本机 标准 none,按原字节数
< 小端 标准 none,按原字节数
> 大端 标准 none,按原字节数
! network(大端) 标准 none,按原字节数
格式符 C语言类型 Python类型 Standard size
x pad byte(填充字节) no value
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I(大写的i) unsigned int integer 4
l(小写的L) long integer 4
L unsigned long long 4
q long long long 8
Q unsigned long long long 8
f float float 4
d double float 8
s char[] string
p char[] string
P void * long
"""
import struct
x = struct.pack('>i', 123456)
print x
print struct.unpack(">i", x)
x = struct.pack('4s', "dsfa")
print x
print struct.unpack("4s", x)
print len("我是你爹")
x = struct.pack('12siii', "我是你爹", 123, 456, 789)
print x
print struct.unpack("12siii", x)
base64
print "# ############################### base64 ################################"
import base64
x = base64.b64encode("fdasfa哦我我我我")
print x
print base64.b64decode(x)
hashlib
print "# ############################### hashlib ################################"
import hashlib
print hashlib.md5('dsaf').hexdigest()
time datetime
print "# ############################time datetime #########################"
import time
import datetime
print time.time() # 当前时间戳
print datetime.datetime.now() # 当前时间
print datetime.date.today() # 当天
print "--------------"
# 时间戳转时间
print datetime.datetime.fromtimestamp(time.time())
# 时间转时间戳
print time.mktime(datetime.datetime.now().timetuple())
# 时间戳转日期
print datetime.date.fromtimestamp(time.time())
# 日期转时间戳
print time.mktime(datetime.date.today().timetuple())
# 从时间获取日期
datetime.datetime.now().date()
# 从时间获取时间
datetime.datetime.now().time()
# 年 月 日 当天星期几
print "----------年 月 日----------"
print datetime.date.today().isoweekday()
print (datetime.date.today() - datetime.timedelta(days=1)).isoweekday()
print datetime.datetime.now().year
print datetime.datetime.now().month
print datetime.datetime.now().day
print datetime.datetime.now().isoweekday()
print datetime.datetime.now().isocalendar()
print "--------------"
# utc时间
print datetime.datetime.utcnow()
# 东八区时间
print str(datetime.datetime.now()) + "+0800"
# 格式 Tue Dec 11 18:07:14 2008
print time.asctime()
# 时间格式化为字符串
print datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
# 字符串解析为时间
print datetime.datetime.strptime("2010-1-1 12:12:02", "%Y-%m-%d %H:%M:%S")
collections
print "################################collections ################################"
# 为不存在的key提供一个默认值,字符串是空串,int是0,各种类型判断为空的数据都是
from collections import defaultdict
d = defaultdict(dict)
d['b'] = 1
print d['b']
print d['a']
# 有序字典,有序是指加入字典的时序
from collections import OrderedDict
d = OrderedDict({})
d['1'] = 1
d['3'] = 3
d['2'] = 2
print d
# 命名元祖,能够像对象一个样初始化和取值
from collections import namedtuple
Person = namedtuple('Person', ['age', 'height', 'name'])
p = Person(1, 185, 'fdsa')
print p.age
print p.height
# 双向队列 append appendleft pop popleft clear remove
from collections import deque
d = deque(maxlen=10)
d.extend([1, 2, 3])
d.append(4)
print d.popleft()
d.appendleft(5)
print d.pop()
print d
itertools
print "# ############################### itertools ##############################"
# itertools 是python的迭代器模块,itertools提供的生成迭代器的函数,相当高效且节省内存
# 无限迭代器count(start[,step])
from itertools import count
for x in count(10, 100):
print x
break
# 无限迭代器 cycle(p)
from itertools import cycle
for x in cycle("ABCD"):
print x
break
# 无限迭代器 repeat(p[,n]) n是重复次数
from itertools import repeat
for x in repeat(10, 3):
print x
# 有限迭代器 python3 将每个元素和之前的元素累加
# from itertools import accumulate
# print accumulate([1, 2, 3, 4])
functools
partial
print "# ############################### functools ##############################"
# partial 简化调用方式,第一个参数是函数对象,后面的参数是函数对象的固定实参
from functools import partial
from operator import add
my_add = partial(add, 1)
print my_add(2)
# reduce
from functools import reduce
def test(x, y):
return x * y
print reduce(test, [1, 2, 3, 4, 5])
wraps
# wraps
#############################以下是不使用wraps的情况,my_function的元数据都丢失了######################
def my_decorator(f):
def wrapper(*args, **kwargs):
print("Calling decorated function")
return f(*args, **kwargs)
return wrapper
@my_decorator
def my_function():
"""This is the docstring of my_function"""
print("Hello, World!")
print(my_function.__name__) # 输出: wrapper
print(my_function.__doc__) # 输出: None
##############################使用wraps后##############################################
from functools import wraps
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
# 在这里可以添加一些额外的功能
print("Calling decorated function")
return f(*args, **kwargs)
return wrapper
@my_decorator
def my_function():
"""This is the docstring of my_function"""
print("Hello, World!")
print(my_function.__name__) # 输出: my_function
print(my_function.__doc__) # 输出: This is the docstring of my_function
contextlib
主要用于简化上下文管理器的创建和使用。上下文管理器是一种在进入和退出某一代码块时,
能够自动执行预定义操作的对象,通常使用 with 语句来管理资源,例如文件、网络连接等
contextmanager
print "# ############################### contextmanager ##############################"
import contextlib
@contextlib.contextmanager
def open_file(file_name, mode):
f = open(file_name, mode)
try:
yield f # 这里会返回给 with 语句使用
finally:
f.close() # 确保文件在退出时关闭
# 使用上下文管理器
with open_file('test.txt', 'w') as f:
f.write('Hello, World!')
closing
import sqlite3
from contextlib import closing
def query_db(db_path, query):
with closing(sqlite3.connect(db_path)) as conn:
cursor = conn.cursor()
cursor.execute(query)
results = cursor.fetchall()
return results
results = query_db('example.db', 'SELECT * FROM my_table')
for row in results:
print(row)
requests
################requests的重试策略#########################
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# 定义重试策略
retry_strategy = Retry(
total=5, # 总共重试5次
status_forcelist=[429, 500, 502, 503, 504], # 对这些HTTP状态码重试
method_whitelist=["HEAD", "GET", "OPTIONS", "POST"], # 针对哪些HTTP方法重试
backoff_factor=1 # 重试时的退避时间指数,例如:1秒,2秒,4秒...
)
# 将重试策略附加到HTTP适配器上
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("http://", adapter)
http.mount("https://", adapter)
# 发起POST请求
try:
response = http.post('https://httpbin.org/post', data={'key': 'value'})
print(response.status_code)
print(response.json())
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
json
# 通过设置全局JsonEncoder,可以自定义处理特定对象的过程
print "# ############################### json ##############################"
from decimal import Decimal
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, Decimal):
return float(o)
super(DecimalEncoder, self).default(o)
print json.dumps({"fda": Decimal(0.22121)}, cls=DecimalEncoder)
python基础
变量赋值
- y = x = x + 1 # 链式赋值
- x = x + 1 # 增量赋值
- x, y, z= 1, 2, 3 # 多元赋值,等号两边是元祖
- y, x = x, y # 交换两个变量的值
标识符
标识符命名
标识符只能使用数字和字母和下划线,标识符必须以字母和下划线开头
关键字
'''关键字(from import as) (class def runturn lambda pass)
(try except else finally raise) (for while continue break)
(if else elif) (and or is in) (global) (yield assert None exec)
'''
# 捕获一般异常
try:
# 可能引发异常的代码
x = 1 / 0
except Exception, e:
# 处理异常
print "An error occurred:", e
# 捕获特定的异常
try:
x = 1 / 0
except ZeroDivisionError, e:
print "Division by zero error:", e
# 捕获多个异常
try:
x = 1 / 0
except (ZeroDivisionError, ValueError), e:
print "An error occurred:", e
'''********在Python3中异常处理的语法与Python2的主要区别在于异常捕获时使用 as 代替 逗号, **********'''
内建标识符(不重要)
python还有一些"内建"标识符,不是关键字,但应该视为系统保留字,不作为他用,但是可以覆盖替换
专有下划线标识符
定义
# 单下划线 _variable、_attribute、_func、_method:表示变量、属性、函数、方法是内部使用的,不应该在模块或类外部使用。只是一个约定,没有强制性。
# 双下划线 __variable、__attribute、__func、__method:变量或方法触发名称改写机制,用于避免子类中可能的命名冲突,使变量或方法更“私有”,可通过_ModuleName__var、_ClassName__func访问。
# 特殊方法 __method__:由 Python 解释器调用的具有特殊意义的方法,如 __init__, __str__
保护属性和方法、私有属性和方法
# _xxx 约定:单下划线前缀 _variable
class MyClass:
def __init__(self):
self._internal_var = 42
class MyClass:
def __init__(self):
self.__private_var = 42 # 被改写为 _MyClass__private_var
def __private_method(self):
print("This is a private method")
###########以上都不会真正限制访问,但它提醒使用者这是一个内部实现细节####################
# 特殊方法(Magic Methods):双下划线前后缀 __method__
# 解释:有一些特殊方法(如 __init__, __str__, __call__ 等),以双下划线开头和结尾。这些方法在 Python 中具有特殊的意义,通常是由 Python 解释器调用的,而不是直接调用。
class MyClass:
def __init__(self, value):
self.value = value
def __str__(self):
return "Value: " + str(self.value)
obj = MyClass(10)
print(obj) # 自动调用 __str__ 方法
模块内部使用、名称改写
# module.py
_internal_var = 42
def _internal_function():
return "This is an internal function"
# module.py
class MyClass:
def __init__(self):
self.__private_var = 99 # _ModuleName__var
def __private_function(self):
return "This is a private function"
# 不管单双下划线都是约定,并不强制限制访问
name
如果模块是被导入,__name__的值为模块名字
如果模块是被直接执行,__name__的值为'__main__'
内存管理
python通过一下方式管理内存
引用计数
Python 中的每个对象都维护一个引用计数,当一个新的引用指向该对象时,引用计数增加;
当引用被删除或设置为其他对象时,引用计数减少。当对象的引用计数降为零时,Python 会自动释放该对象占用的内存。
优点:
简单高效,即时清理。
缺点:
循环引用问题:两个对象相互引用,可能导致引用计数永远不会为零,从而导致内存泄漏。
标记-清除
如何解决循环引用的问题?
标记-清除策略。所有的对象在内存中构成了多个图结构,
从根集合(全局变量,静态变量,当前正在执行的函数的局部变量)出发标记所有能到达的对象,这是标记阶段;
然后是清除阶段是删除所有不可达未标记的对象
如下图:a、b不可达被清除
内存分配
python提供了对内存的垃圾收集机制,但它不是将内存释放给操作系统
1. pymalloc为了提升执行效率,引入了一个内存池机制,用于管理小块内存
2.所有小于512字节的对象都使用Pymalloc分配内存,对于大对象,Python 直接使用系统的内存分配器(如 malloc 或 free)进行管理
3.python对象,如整数 浮点数 列表都有其互相隔离的内存池,整数的内存释放后也不会分配给浮点数
优点:加快内存分配和释放的速度
python对象
身份
# 在 Python 中,可以使用内置函数 id() 来获取对象的身份标识,通常是对象在内存中的地址
a = [1, 2, 3]
print(id(a)) # 输出对象 a 的身份标识
类型
# 类型定义了对象的行为和属性,即对象能够做什么以及它的存储内容。对象的类型决定了它有哪些方法和操作,可以如何与之交互。
a = [1, 2, 3]
print(type(a)) # 输出对象 a 的类型,即 <class 'list'>
值
# 值是对象所包含的数据或信息,它可以改变也可以不改变,取决于对象是否是可变的(mutable)
a = [1, 2, 3]
print(a) # 输出对象 a 的值,即 [1, 2, 3]
python的类型
1.基本类型:整型 长整型 浮点型 复数型 布尔型 字符串 列表 字典 元祖
2.内建类型:文件 集合 函数 模块 类
None,python的null对象
1.所有标准类型都可用以布尔测试, None False 0 0.0 空串 空列表 空元祖 空字典的布尔测试都为空
2.自定义类实例的布尔测试,根据类定义的__nonzero__返回的值测试布尔值
内部类型
代码 帧 跟踪记录 切片 Xrange
1.代码对象是编译过得python源代码片段,是可执行对象。可以通过eval()函数来执行
2.每次函数调用都会产生一个新得帧,每一个帧对象都会产生一个c栈帧,也就是堆栈。就是push寄存器值进入堆栈
3.当使用python的切片语法时,就会创建切片对象,切片包括步进切片,多维切片,省略切片
4.Xrange()会生成一个Xrange对象,Xrange比range更节省内存,range无法完成超大数据集合
对象身份比较
python对于不可变对象 整数和字符串会很高效的缓存他们,所以对于两次定义变量赋值同一个整数,所获取到的身份id都一样
标准内建函数
type() cmp() str() repr() type() isinstance()
type 可以判断对象类型,创建动态类
cmp 比较对象数值大小,自定义对象根据__cmp__返回值比较
str repr str生成的字符串更加友好,repr()生成的字符串对python解释器更加友好
isinstance 判断类型
类型工厂函数
int() long() float() complex() str() list() dict() tuple()
set() fronzenset() object() unicode() basestring()
type() super()
python可变对象和不可变对象
不可变对象 元祖 字符串 数字类型
可变对象 列表 字典 集合
数字
除法
python有两种除法
1.地板除 2.真正的除法
地板除向下取整,真正的除法保留小数。传统的除法单斜杠/根据操作数选择(地板除还是精确除法)。操作为整数执行地板除,操作数为浮点数执行精确除法
不考虑操作数:
python2可以from __future__ import division使用精确除法,使用双斜杠//执行地板除
python3里面单斜杠/执行精确除法 双斜杠//为地板除
数字类型函数
int long float complex
abs() 求绝对值
divmod() 把除法和取余结合了 例子:divmod(10, 3)结果(3, 1)
pow() 幂运算 例子:pow(10,2)结果100
round() 对浮点数进行四舍五入 例子:round(0.2356, 2)结果0.23
hex() 转换一个任意进制的整数到16进制 例子:hex(15)结果'0xF'
oct() 转换一个任意进制的整数到8进制
ord() a转换为97 字符串转换为数字 例子:ord('a')结果97
chr() 数字转换为字符 例子:chr(97)结果'a' chr(25105)结果'我'
python常用的数值处理模块
# decimal array math operator random
# radom包含多个伪随机数发生器,它以当前时间戳为随机数种子
# random里面比较有用的函数randint choice
from decimal import Decimal
# 创建 Decimal 对象
num1 = Decimal('0.1')
num2 = Decimal('0.2')
# 精确的十进制运算
result = num1 + num2
print(result) # 输出:0.3
# ----------------------------------------------------------------------------
from array import array
# 创建一个数组
my_array = array('i', [1, 2, 3, 4, 5])
# 访问数组元素
print(my_array[0]) # 输出:1
# 修改数组元素
my_array[0] = 10
print(my_array) # 输出:array('i', [10, 2, 3, 4, 5])
# ----------------------------------------------------------------------------
import math
# 计算平方根
sqrt_result = math.sqrt(25)
print(sqrt_result) # 输出:5.0
# 计算正弦值
sin_result = math.sin(math.pi / 2)
print(sin_result) # 输出:1.0
# ----------------------------------------------------------------------------
import operator
# 使用操作符函数进行加法运算
add_result = operator.add(5, 3)
print(add_result) # 输出:8
# 使用操作符函数进行字典合并
dict1 = {'a': 1}
dict2 = {'b': 2}
merge_result = operator.concat(dict1, dict2)
print(merge_result) # 输出:{'a': 1, 'b': 2}
# ----------------------------------------------------------------------------
import random
# 生成随机整数
random_int = random.randint(1, 10)
print(random_int)
# 生成随机浮点数
random_float = random.uniform(0, 1)
print(random_float)
序列:字符串 列表 元祖
序列类型操作符和内建函数和方法
操作符,内建函数,方法 | string | list | tuple |
---|---|---|---|
[] | * | ||
() | * | ||
“” | * | ||
append() | * | ||
capitalize() | * | ||
center() | * | ||
chr() | * | ||
cmp() | * | * | * |
count() | * | * | |
decode() | * | ||
encode() | * | ||
endswith() | * | ||
extend() | * | ||
find() | * | ||
hex() | * | ||
index() | * | * | |
insert() | * | ||
isdecimal() | * | ||
isdigit() | * | ||
islower() | * | ||
isupper() | * | ||
join() | * | ||
len() | * | * | * |
list() | * | * | * |
ljust() | * | ||
lower() | * | ||
strip() | * | ||
max() | * | * | * |
min() | * | * | * |
ord() | * | ||
upper() | * | ||
zfill() | * | ||
[]slice | * | * | * |
[:] | * | * | * |
* | * | * | * |
% | * | ||
+ | * | * | * |
in | * | * | * |
not in | * | * | * |
字符串的内建函数
cmp(str1, str2) // 对ASCII码值进行比较 相等返回0,str1>str2返回1,str1<str2返回0
len('abc') // 返回字符数或字节数
max('abc') // 返回ASCII最大的字符
min('abc') // 返回ASCII最小的字符
enumerate('abc') // 返回一个enumerate对象,调用next函数获取一个元组,最后抛出一个stopiteration错误 (0,'a') (1,'b') (2,'c')
zip('abc', 'cba', 'elk') // 对n个序列对象进行相同下标元素组合,以最短的序列对象为基准 ('a', 'c', 'e') ('b', 'b', 'l') ('c', 'a', 'k')
chr(65) // 数字转asc字符
unichr(12345) // 数字转Unicode python已删除该函数
ord('a') // ord('\u2345') asc字符转数字
.capitalize() // 首字母大写
.center(width) // 字符串居中,两边用空格填充至给定的长度
.count(str) // 返回str在string里面出现的次数
.decode() // 解码string
.encode() // 编码字符串
.startwith(obj) // 以obj开头,返回True和False
.endswith(obj) // 以obj结尾,返回True和False
.find(str) // 查找str,找到返回索引,没找到返回-1
.index(str) // 查找str,找到返回索引,没找到抛出ValueError
.isdigit() // 只否包含数字,是返回true,不是返回false
.islower() // 是否小写,是True,不是False
.isupper() // 是否大写,是True,不是False
.join(seq) // 以string作为分隔符,将seq中所有元素合并为一个新字符串
.replace(str1, str2) // 把字符串中的str2替换为str1
.strip() // 删除头尾空格
.split(str) // 以str为分隔符切割字符串
.zfill(width) // 指定一个长度向右对齐,左边填充0
.ljust // 指定一个长度向左对齐,右边填充空格
操作字符串相关的模块
string re struct base64 md5 hashlib
列表内建函数
.append(obj) // 向列表中添加obj
.count(obj) // 返回obj在列表中出现的次数
.extend(seq) // 把序列seq的内容添加到列表中
.index(obj) // 返回obj在list中的索引,没有则引发ValueError异常
.insert(index, obj) // 在索引为index的位置插入obj
.pop(index) // 根据index弹出一个元素,不存在返回IndexError。默认从队列尾弹出
.reverse() // 原地翻转列表
.sort() // 原地列表排序
注意:sort extend reverse没有返回值,但reversed() sorted()可返回一个对象
栈和队列
列表可以用来构建栈和队列
利用list的内建函数append()和pop()可以用来构建栈
利用List的内建函数append()和pop(0)可以用来构建队列
单元素元组
('1321') 如果定义元组的时候括号内不加逗号会被认为是分组操作符,最后定义成一个字符串
unicode和ascii字符集
内存中其实只存字节序,并不表示一段内存是什么字符。取决于读取这段内存的程序怎么看待他(是字符集还是字符集的编码形式)
unicode字符集 在内存中存储的形式
0000—0FFF 8000—8FFF 10000—10FFF 20000—20FFF 28000—28FFF E0000—E0FFF
asc字符集 在内存中存储的形式
00-7F
字符集 编码方式 字节序
ASCII ascii -->
GBK gbk -->
BIG5 big5 -->
gb2312 EUC-CN -->
Unicode utf8 utf16 utf32 -->
编码示例:unicode按照utf8编码为字节序
U+77E5 + utf8 = E79FA5
coding:utf8和setdefaultencoding
这两个作用不一样,
1. # coding:utf-8
作用是定义源代码的编码. 如果没有定义, 此源码中是不可以包含中文字符串的
2. sys.getdefaultencoding()
是获取解释器默认的编码格式
原始字符串
如果字符串中有\n \t的,这些字符不进行转义操作。 加了r的原始字符串会比字符串长度多1
python为序列类型提供以下函数
enumerate(iter) 接受一个可迭代对象作为参数,返回一个enumberate对象,该对象由每个元素的index和元素值组成
len(seq)
max(iter, key=None) or max(arg0, arg1..., key=None)
min(iter, key=None) or min(arg0, arg1... key=None)
reversed() 接受一个序列
sorted(iter,cmp=None, key=None,reverse=False)
接受一个序列对象,三个可选参数,cmp可选参数接受一个函数对象,key可选参数也是接受一个函数对象,reverse是否反转
cmp的函数对象是接受两个参数,函数对象返回1 -1 0。key的函数对象接受一个参数
sum(seq) 返回总和
zip([[it0, it1,... itN]]) 返回一个列表,其第一个元素是it0,it1,...这些元素的第一个元素组成的一个元祖,第二个...,类推
普通切片和递进切片和多维切片
### 普通切片
s = "abcdefg"
print s[1: 2]
### 递进切片
step:正负数均可,其绝对值大小决定了切取数据时的‘‘步长”,而正负号决定了“切取方向”,正表示“从左往右”取值,负表示“从右往左”取值。当step省略时,默认为1,即从左往右以步长1取值。
start_index:表示起始索引(包含该索引对应值);该参数省略时,表示从对象“端点”开始取值,至于是从“起点”还是从“终点”开始,则由step参数的正负决定,step为正从“起点”开始,为负从“终点”开始。
end_index:表示终止索引(不包含该索引对应值);该参数省略时,表示一直取到数据“端点”,至于是到“起点”还是到“终点”,同样由step参数的正负决定,step为正时直到“终点”,为负时直到“起点”。
s[start_index:end_index:step]
s = "abcdefg"
print s[1:3:-2]
# ###################################多维切片#########################################
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
submatrix = [row[0:2] for row in matrix[1:3]] # 结果: [[4, 5], [7, 8]]
字符串的格式化操作符
"%x" % 108 # 6c
"%f" % 1234.5678 # 1234.5678
"%.2f" % 1234.5678 # 1234.56
"%04d" % 1 # 0001
"%s" % 12345 # 12345
"MM/DD/YY = %02d/%02d/%d" % (2, 15, 1967) # MM/DD/YY = 02/15/1967
Template (f字符串更好用)
from string import Template
s = Template('There are ${howmany} ${lang} Quotation Symbols')
print s.substitute(lang='Python', howmany=3)
字典的关键字
字典的关键字必须是一个可hash的类型,可hash的类型指的是不可变对象,对自定义对象需要重写__hash__方法,确保对象生命周期内每次hash是同一个值
深拷贝和浅拷贝
deepcopy 深拷贝 使用深度遍历算法深入对象树开辟内存并赋值值
copy 直接把当前对象的元素值拷贝一遍,不会深入引用去检查
浅拷贝
import copy
original_list = [1, 2, [3, 4]]
shallow_copied_list = copy.copy(original_list)
shallow_copied_list[2][0] = 100
print(original_list) # 输出: [1, 2, [100, 4]]
print(shallow_copied_list) # 输出: [1, 2, [100, 4]]
深拷贝
import copy
original_list = [1, 2, [3, 4]]
deep_copied_list = copy.deepcopy(original_list)
deep_copied_list[2][0] = 100
print(original_list) # 输出: [1, 2, [3, 4]]
print(deep_copied_list) # 输出: [1, 2, [100, 4]]
映射和集合类型
字典
字典的key和value本身是无序的,collections模块里面有个OrderedDict可以构建有序字典
字典类型方法
.clear() // 删除字典中所有元素
.copy() // 返回字典的一个副本,浅拷贝
dict.fromkeys(seq, value=None) // 创建并返回一个新字典,以seq中的元素做该字典的键,value做该字典中所有键对应的初始值
.get(key, default=None) // 获取值
.has_key(key) // 判断值是否存在
.items() // 返回一个包含键值对的元组列表
.keys() // 返回一个包含所有键的列表
.iteritems() // 返回一个键值对的迭代器
.iterkeys() // 返回一个字典key的迭代器
.itervalues() // 返回一个值的迭代器
.pop(key) // 返回一个指定key的值,然后删除,如果不存在,切没有给出默认值,引发KeyError异常 (del d['key'])
.setdefault(key, default=None) // 如果键不存在于字典中,就会设置键值对到字典中
.update(dcit2) // 将dict2的键值对添加到字典dict
.values() // 返回一个包含字典中所有值的列表
集合的操作
集合分为可变集合和不可变集合
in 是...的成员
not in 不是...的成员
== 等于
!= 不等于
< 是...的子集
> 是...的超集
& 求交集
| 求合集
- 求差集
^ 对称差集
集合内建函数
len()
set()
frozenset()
issubset()
issuperset()
union() 并集
intersection() 交集
difference() 差集
copy() 赋值集合,浅赋值
add() 添加到集合
remove(obj) 将Obj从集合中删除
pop() 弹出任何一个元素
错误和异常
什么错误和异常
错误是语法上或是逻辑上的,导致程序无法正常编译或解释,这必须在程序执行前纠正
异常是正常逻辑流之外发生的错误行为,主要包括两部分,异常发生点和异常发生后的处理措施
写法
try-except-finally 可以有多个except语句,except可以用as为异常取别名,python2为逗号,
try:
...
except ValueError as e:
pass
except ZeroDivisionError, ex:
pass
else:
pass # 当try块中的代码未引发异常时,执行else块中的代码
finally:
pass # 无论是否发生异常,finally块中的代码都会执行。它通常用于清理资源(例如关闭文件)
try:
...
except (ValueError, ZeroDivisionError), ex:
pass
finally:
pass
1. 引发异常
在Python中,异常可以由程序自身引发,或者通过raise语句手动引发
2. 捕获异常
异常发生后,Python会沿着调用栈向上查找处理这个异常的代码。可以使用try和except块来捕获和处理异常。
3. 异常传播
异常引发后在当前调用栈匹配except块,如果没有找到匹配的except块,它会沿着调用栈继续向上传播,直到遇到另一个合适的except块。
如果异常直到最顶层都没有被捕获,Python会终止程序,并打印错误的回溯信息。
上下文管理
# (使用contextlib包的contextmanager更方便)
# with语句
# with相较于try-except-finall写法更加简洁,能够对于文件,数据库连接的自动释放处理,但with语句仅能工作于支持上下文管理协议的对象file decimal.Context threading.Lock
# 上下文管理协议
# 是指实现了 __enter__,__exit__方法的对象。 with语句块执行前进入__enter__方法,其返回值会赋值给as后的变量名,with语句块执行结束后会执行__exit__方法。
# 所以很多共享资源在enter中初始化,exit中销毁。当with语句块存在异常时,__exit__返回真吞掉异常,返回假则抛出异常
class Foo:
def __init__(self,aa):
self.aa = aa
def __enter__(self):
print('run enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('run exit')
print(exc_type)#异常类 如:NameError
print(exc_val)#异常值 如:name 'myname' is not defined
print(exc_tb)#追踪信息 如:Traceback (most recent call last): xxxx
return True
断言
断言成功不采取任何措施,断言失败抛出AsserttionError异常
标准异常
BaseException 所以异常的基类
Exception 常规错误的基类
IOError 输入输出操作失败
MemoryError 内存溢出
SystemError 系统错误
SyntaxError 语法错误
ZeroDivisionError 除数为0
AsserttionError 断言异常
AttributeError 没有属性
IndexError 序列中没有此索引
KeyError 映射中没有这个键
NameError 未声明对象
TypeError 类型无效 abs('s')
ValueError 传入无效的参数 int('s')
UnicodeDecodeError
UnicodeEncodeError
StopIteration 迭代器没有更多的值
函数编程
形参实参
# python 形参的定义顺序是:位置参数 可变长位置参数 可变长关键字参数
def test(positional_arg, *args, **kwargs):
pass
# python 实参的定义顺序是:实际数值在关键字参数前面,然后按顺序匹配形参
test('alice', 18825415178, 21, socre=100, subject='english')
关键字参数
# 调用者通过函数的参数名来区分参数,这样的规范允许缺少参数或者不按顺序,因为解释器是根据给出的关键字来匹配参数的值
def test(positional_arg, *args, socre=None, subject=None):
pass
test('alice', 18825415178, 21, subject='english')
默认值参数
# 在声明函数的时候指定了默认参数,因为指定了默认值,在传参的时候不向该函数传入参数也是允许的
def test(positional_arg, *args, socre=100):
pass
test('alice', 18825415178, 21)
位置参数
# 定义函数时位置参数必须位于可变参数前面
def test(a, v, *args):
pass
可变长参数
可变长参数分为两种参数,非关键字可变长参数和关键字可变长参数,例如*args **kwargs
*args 接收所有的位置参数,汇聚成一个元组,赋值给args
**kwargs 接收所有键值对参数,汇集成一个字典,赋值给kwargs
装饰器
函数装饰器
一个函数装饰器就是一个函数,它接收一个函数作为参数,并返回一个新的函数。
def decorator(func):
def wrap(*args, **kwargs):
print("decorator before")
f = func(*args, **kwargs)
print("decorator after")
return f
return wrap
def func():
print(f"hello!")
func1 = decorator(func)
func1()
# 以上代码等价于
'''
@decorator
def func():
print(f"hello!")
func()
'''
################################ 如果装饰器是带参装饰器,那么等价的形式大概是这样的 #########################################
def outer_decorator(*param):
def decorator(func):
def wrapper(*args, **kwargs):
# 在这里可以使用外层的参数
print(f"Decorator parameter: {param}")
return func(*args, **kwargs)
return wrapper
return decorator
@outer_decorator(1, 2, 3)
def func():
pass
func()
# 以上代码等价于
'''
def func():
pass
func1 = decorator(1, 2, 3)(func)
func1()
'''
类装饰器
一个类装饰器就是一个函数,它接收一个类作为参数,并返回一个新的类。
类装饰器的目的就是为了在类对象被实例化之前执行一段额外的逻辑
####################################### 类装饰器 #############################################
def decorator(cls):
print "decorator"
class wrapper():
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)
def __getattr__(self, name):
return getattr(self.wrapped, name)
return wrapper
@decorator
class cls():
def __init__(self, x, y):
print "init"
self.attrx = x
self.attry = y
def method(self):
return self.attrx, self.attry
c = cls(3, 4)
print(c.attrx)
print(c.attry)
print(c.method())
多个装饰器的调用顺序
# 被多个装饰器包裹。执行过程类似于递归
def wrapper1(fn):
def inner(*args, **kwargs):
print("wrapper1 before {}".format(fn.__name__))
fn()
print("wrapper1 after")
return inner
def wrapper2(fn):
def inner(*args, **kwargs):
print("wrapper2 before {}".format(fn.__name__))
fn()
print("wrapper2 after")
return inner
@wrapper2
@wrapper1
def target():
print("this is target")
target()
# 等价于 wrapper2(wrapper1(target))()
# 执行过程是根据装饰器书写顺序从上到下,然后再从下到上,类似于函数栈帧,我叫做U字母型调用
# wrapper2 before inner
# wrapper1 before target
# this is target
# wrapper1 after
# wrapper2 after
函数式编程
# python不是函数式编程语言,但python支持一些函数式编程的构建,如map() filter() reduce()
# 什么是高阶函数:一个函数的参数为另一个函数或者一个函数返回值为另一个函数,则该函数为高阶函数
reduce
reduce(func, seq[, init]) 将序列的元素1和元素2进行计算,结果继续同元素3计算,然后结果同元素4计算,依次类推,直到最后一个元素 数学描述:reduce(f, S) = f(f(f(f(a1, a2), a3), ...), an)
图解如下:
from functools import reduce
scientists =({'name':'Alan Turing', 'age':105, 'gender':'male'},
{'name':'Dennis Ritchie', 'age':76, 'gender':'male'},
{'name':'Ada Lovelace', 'age':202, 'gender':'female'},
{'name':'Frances E. Allen', 'age':84, 'gender':'female'})
def group_by_gender(accumulator , value):
accumulator[value['gender']].append(value['name'])
return accumulator
grouped = reduce(group_by_gender, scientists, {'male':[], 'female':[]})
print(grouped)
map
# map(func, seq1[, seq2...]) 接收一个函数和list,并将函数依次作用于list或多个list的每个元素上,得到一个新得list并返回
# map(lambda x: x*x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) // [1,4,9,16...]
# map(lambda x, y: x + y, [1,3,5], [2,4,6]) // [3, 7, 11]
# map(None, [1,3,5], [2,4,6]) // [(1, 2), (3, 4), (5, 6)]
# 图解如下:
filter
# filter(func, seq) 将序列的每个元素传递给函数对象,函数对象返回True则保留元素,最终返回一个过滤后的序列
# filter(lambda n: n % 2 == 1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# 图解如下:
偏函数
偏函数在functools模块中,partial返回一个函数对象,偏函数可以简化调用方式
from operator import add,mul
from functools import partial
add1 = partial(add, 1)
add1(10)
闭包
如果在一个内部函数里,对外部函数变量进行引用(但不是全局变量),那么内部函数被认为是闭包,定义在外部函数内但由内部函数使用的变量被称为自由变量
自由变量跟闭包函数相关,跟外部函数没有任何关系,自由变量存放在闭包函数的名称空间中,自由变量会影响下一次闭包实例调用的结果
def my_func(*args):
fs = []
for i in xrange(3):
def func():
return i * i
fs.append(func)
return fs
fs1, fs2, fs3 = my_func()
print fs1()
print fs2()
print fs3()
# 输出 4 4 4
模块
路径搜索
Python在导入模块时,会按照一定顺序搜索模块文件的位置。这个顺序由sys.path变量决定,它是一个包含多个路径的列表。
sys.modules dict,模块名为key,路径为value
sys.path 查找模块的搜索目录列表
sys.path.append 新增搜索目录
sys.paht.insert(index, path)
sys.path中通常包含以下几个路径:
- 当前脚本的目录:如果在终端运行脚本,这个路径是脚本所在的目录。
- PYTHONPATH环境变量:用户可以设置的自定义路径。
- 标准库路径:Python自带的标准库位置。
- 第三方库路径:通常是site-packages目录。
命名空间
定义
Python 作用域遵循 LEGB 规则,即 Local -> Enclosing -> Global -> Built-in 的查找顺序。当在一个作用域中引用变量时,Python 会首先在局部作用域中查找,然后依次向上查找直到找到对应的标识符。如果在任何一个作用域中找不到变量,则会引发 NameError。
命名空间的类型
Python有几种不同的命名空间,通常包括以下几种:
- 内置命名空间:包含Python内置的函数和异常,例如len()、Exception等。它在Python解释器启动时创建,且在程序运行期间一直存在。
- 全局命名空间:由当前模块创建,包含在模块顶层定义的变量和函数名。每个模块有自己的全局命名空间。
- 局部命名空间:由函数或方法调用时创建,包含函数内部定义的变量。函数调用结束后,这个命名空间就会被销毁。
- 闭包命名空间:当一个函数在另一个函数内部定义时,这个内部函数可以访问外部函数的局部变量。这些变量的命名空间称为闭包命名空间。
作用域
定义
作用域是Python程序中名字可见的区域。它决定了一个名字(变量或函数)在代码的哪些部分可以被引用
作用域的类型
Python的作用域规则遵循LEGB顺序,即:
- Local(局部作用域):函数内部定义的名字。优先级最高。
- Enclosing(嵌套作用域):外层函数的局部作用域。在嵌套函数中,内部函数可以访问外层函数的局部变量。
- Global(全局作用域):模块的顶层定义的名字。优先级低于局部和嵌套作用域。
- Built-in(内置作用域):Python解释器内置的名字,优先级最低。
命令空间和作用域的关系
- 命名空间是用于存储名字和对象之间映射的容器,而作用域是定义在何处可以访问这些名字的区域。
- 作用域决定了哪个命名空间中的名字在某个位置是可见的。Python解释器会根据LEGB规则依次搜索不同的命名空间来解析变量。
模块内建函数
globals() 返回全局名称空间的字典
locals() 返回局部名称空间的字典,如果放到全局作用域调用,还是返回全局名称空间
reload(module) 重新导入一个已经导入的模块。reload会导致模块被重新执行一次和import不同
__import__("test.ty") 导入模块,主要用于反射或者延迟加载模块,如果模块已经被导入了,则模块并不会再执行一次
INIT.py文件
定义
__init__.py 文件的作用主要有以下几点:
1.将目录标识为Python包
2.配置包的初始状态、设置包的全局变量、导入子模块或子包等
3.模块和类的快捷导入
模块和类的快捷导入
- 在__init__.py 文件中,可以显式导入包中的特定模块、类或函数,这样在使用该包时,可以更方便地进行导入。例如,可以在__init__.py 中导入包中的某些模块或类,使得使用者可以直接通过import package 的方式来导入这些模块或类,而不需要深入到具体的子模块。
# 在 mypackage/__init__.py 中
from .module1 import ClassA
from .module2 import funcB
- 这样使用者可以直接通过以下方式访问:
from mypackage import ClassA, funcB
- 控制导入的内容:通过在__init__.py 文件中定义__all__ 变量,可以控制使用from package import * 时,包中哪些模块、类或函数会被导入
__all__ = ['module1', 'module2']
面向对象
类属性和实例属性
class A(object):
# 类属性,在类名称空间中
CLASS_NAME = 1
def __init__(self):
"""
1.设置属性
2.构造函数不能返回任何值,否则会导致TypeError
"""
# 实例属性,在实例名称空间中
self.a = 1
def __new__(cls, *args, **kwargs):
"""
cls: 类对象
args: 实例化对象时传递给类构造函数的位置参数,如 A(1,2)中的1和2两个数字
kwargs: 实例化对象时传递给类构造函数的关键字参数,如 A(1,2,name='alice')中的name
"""
return super().__new__(cls)
def __del__(self):
"""
对象引用计数为0的时候调用
"""
pass
def test(self):
pass
a = A()
a.test()
A.test(a)
# __init__ 构造函数 __del__析构函数
#(1)实例中属性的查找顺序
#实例的名称空间->类名称空间->继承树中基类的名称空间。
#(2)修改类属性
#修改类属性只能使用类名,无法使用实例来修改
#(3)self
#self就是对象实例本身,在其他语言叫做this
#(4)调用实例方法的两种方式
#a=A()
#a.test()
#A.test(a)
#(5)类和对象的__dict__
#类的静态方法 类方法 类变量都是放在类__dict__中的
#对象的__dict__中存储了实例的属性
__new__和__init__的区别
- **
__new__
**负责创建并返回实例,控制实例的创建过程 - **
__init__
**负责初始化已经创建的实例,设置实例的初始状态 - **
__del__
**它在对象被垃圾回收(即对象的引用计数归0)时被调用,主要用途是释放资源(如文件、网络连接等) - 通常情况下,你只需要使用
__init__
方法,__new__
只在你需要定制对象的创建过程时使用(如在自定义不可变类型或实现单例模式时)
继承
定义
一个子类可以继承它父类的
实例属性、类属性、实例方法、类方法、静态方法、特殊方法、
嵌套类、描述符、property属性、
保护属性、保护方法、私有属性、私有方法,
以及整个继承链上的所有内容。
class Dog(object):
NAME = 1
ins = None
def __new__(cls, *args, **kwargs):
print args, kwargs
return super(Dog, cls).__new__(cls, *args, **kwargs)
def __init__(self, age):
self.age = age
@staticmethod
def tet():
print "static"
@classmethod
def clsmethod(cls):
print cls.NAME
def bark(self):
print "wang wang ..."
class Teddy(Dog):
def __new__(cls, *args, **kwargs):
return super(Teddy, cls).__new__(cls, *args, **kwargs)
def __init__(self, age):
super(Teddy, self).__init__(age)
def bark(self):
print "w w ..."
teddy = Teddy(1)
print teddy.__dict__ # {'age': 1}
print Teddy.__dict__ # {'__module__': '__main__', '__doc__': None, 'bark': <function bark at 0x7fb691e0c140>, '__init__': <function __init__ at 0x7fb691e0c0c8>, '__new__': <staticmethod object at 0x7fb691e044b0>}
#(1)重写__init__不会自动调用基类的__init__,需要主动调用
#(2)使用 super()的漂亮之处在于,你不需要明确给出任何基类名字 如:super(Teddy, self).__init__(age) ,格式super(CurrentClass, cls).__new__(cls, *args, **kwargs)
特殊方法
class Test(object):
def __init__(self, x):
self.x = x
self.d = {}
def __call__(self, *args, **kwargs):
"""
使对象可以用像函数一样调用
"""
print "__call__"
def __cmp__(self, other):
"""对应内建函数cmp()"""
print "__cmp__"
return 1 if self.x > other.x else -1 if self.x < other.x else 0
def __len__(self):
"""对应函数len()"""
return len(self.x)
def __nonzero__(self):
"""对应bool()"""
return True
def __contains__(self, item):
"""对应 in 表达式 """
return item in self.x
def __lt__(self, item): # <
pass
def __gt__(self, item): # >
pass
def __le__(self, item): # <=
pass
def __ge__(self, item): # >=
pass
# __call__ 比如namedtuple partial都是通过__call__来实现的
test = Test(1)
test()
# __cmp__
a = Test(10)
b = Test(10)
print cmp(a, b)
# __len__
a = Test('fdsa')
print len(a)
# __nonzero__
print bool(a)
# __contains__
a = Test("fdsafdas")
print "a" in a
# ########################## 描述符 ###############
# 用于控制对类属性的访问,在多数情况下用于实现高级的属性管理和数据验证 (Pydantic和django的字段验证都是这种方式)
class Typed(object):
def __init__(self, key, exc_type):
self.key = key
self.exc_type = exc_type
def __get__(self, instance, owner):
"""
用于访问属性,返回属性的值,所请求的属性不存在的情况下抛出AttributeError异常
instance 被描述类的实例
owner 被描述类的类对象
"""
print instance, owner
return instance.__dict__[self.key]
def __set__(self, instance, value):
"""
将在属性设置值的过程中调用,没有任何返回
instance 被描述类的实例
value 被描述类的属性值
"""
if not isinstance(value, self.exc_type):
raise TypeError
instance.__dict__[self.key] = value
def __delete__(self, instance):
"""
控制删除操作,没有任何返回
instance 被描述类的实例
"""
instance.__dict__.pop(self.key)
class Person(object):
name = Typed('name', str)
age = Typed('age', int)
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('fda', 1) # __set__
print p.name # __get__
del p.name # __delete__
# ################################ 对象具有切片功能 ######################
# __getslice__、__setslice__、__delslice__:让对象具有普通切片功能
# 对对象进行递进切片需要实现__getitem__。 __getitem__会接收一个slice对象
class Foo(object):
save_list = [1, 2, 3, 4, 5, 6, 34, 23, 5]
def __getslice__(self, i, j):
print "__getslice__:"
return self.save_list[i: j]
def __setslice__(self, i, j, sequence):
print "__setslice__:"
self.save_list[i:j] = sequence
print self.save_list
def __delslice__(self, i, j):
print "__delslice__:"
del self.save_list[i: j]
print self.save_list
def __getitem__(self, item):
if isinstance(item, slice):
return self.save_list[item.start: item.stop: item.step]
return self.save_list[item]
obj = Foo()
result = obj[1: 2] # __getslice__
print(result)
obj[0: 1] = [23, 22, 15, 4] # __setslice__
del obj[4:] # __delslice__
print "------------------"
print obj[::-1] # __getitem__
# ############################# 让对象可以像字典一样取值和赋值 ###############
# __setitem__ __getitem__ 让对象像字典一样操作
class Tag:
def __init__(self):
self.change = {'python': 'This is python',
'php': 'PHP is a good language'}
def __getitem__(self, item):
print('调用getitem')
return self.change[item]
def __setitem__(self, key, value):
print('调用setitem')
self.change[key] = value
a = Tag()
print(a['php']) # __getitem__
a['php'] = 'PHP is not a good language'
print(a['php']) # __setitem__
# ############################## __getattr__ __setattr__ __delattr__ ###############
# 在重写__setattr__ __delattr__方法的时候千万不要重复设置值造成死循环
class A(object):
def __init__(self, value):
print "into __init__"
self.value = value
def __getattr__(self, item):
"""
访问的属性不存在于对象,则会进入方法_getattr__
"""
print "not found for item"
return 1
def __setattr__(self, name, value):
"""
对属性设置值的时候,会调用到这个方法
"""
print "into __setattr__"
super(A, self).__setattr__(name, value)
def __delattr__(self, item):
"""
显示删除属性的时候会进入这个方法
"""
print "del attribute"
super(A, self).__delattr__(item)
a = A(10) # into __init__ into __setattr__
print a.value # 10
print a.name # not found for item
del a.value # del attribute
######################### 拦截属性 __getattribute__ ########################
class Tree(object):
def __init__(self, name):
self.name = name
self.cate = "plant"
def __getattribute__(self, *args, **kwargs):
"""
属性拦截器,每次访问的对象属性的时候都会先进入该方法
"""
print "__getattribute__"
return super(Tree, self).__getattribute__(*args, **kwargs)
aa = Tree("大树")
print(aa.name) # 大树
print(aa.cate) # plant
print(aa.fdf) # AttributeError
######################### @property #################################
# 让方法像属性一样操作
class Student:
def __init__(self):
pass
@property
def age(self):
return self.value
@age.setter
def age(self,value):
if isinstance(value,int) and 0<value<100:
self.value=value
else:
print("请输入合法的年龄")
stu = Student()
stu.age = 10
print(stu.age) # 10
内建函数
issubclass(sub, sup) 判断一个类是另一个类的子类或子孙类
isinstance(obj, classes) 判断一个对象是另一个给定类的实例
hasattr(object, name)
getattr(object, name, default)
setattr(object, name, value)
delattr(object, name)
dir(object) 作用在实例上查看实例的所有方法所有属性以及一些特殊方法
super(type[, obj])
多线程
import threading
a = threading.Thread(target=t, args=("fda",))
def t(dsa):
print "fdsa %s" % dsa
a.setDaemon(True)
a.start()
# 多进程实现真正的并发
from multiprocessing import Process
import time
Process(target=func).start()
socket
import socket
import sys
from thread import *
HOST = ''
PORT = 8888
# 创建连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 绑定主机和端口
s.bind((HOST, PORT))
except socket.error, msg:
sys.exit()
# 开始监听
s.listen(10)
def clientthread(conn):
# 发送消息到客户端
conn.send('Welcome to the server. Type something and hit enter\n')
while True:
# 接收消息
data = conn.recv(1024)
reply = 'OK...' + data
if not data:
break
# 发送消息
conn.sendall(reply)
conn.close()
while 1:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
start_new_thread(clientthread, (conn,))
s.close()
python基本库
import os