再探Python:再次学习以补充知识。这次学习聚焦于巩固Python基础,填补之前的知识空白。
字符串的转义问题
字符串中的转义问题
| c = 'C:\windows\nt' |
| c = 'C:\\windows\\nt' |
更简单的方式,r前缀将字符串不要转义了
前缀r,把里面的所有字符当普通字符对待,则转义字符就不用转义了
| a = 'abc' |
| b = 123 |
| c = f'{a}********{b}' |
| c |
| 'abc********123' |
这里说明一下f
是用来构造字符串的。
方便字典value的引入到字符串
| "My name is %(name)s, I'm %(age)d" % {'age':20, 'name': 'Jerry'} |
format方式
| "{}". format ((1,22)) |
| "{0[1} --- {0[0]}".format((1,22)) |
布尔值
False
等价布尔值,相当于bool(value)
字符串的类型比较
| type(list), type(str) ,type(type) |
| (type,type,type) |
| |
| type(True) == bool |
| True |
| isinstance(1, int) |
| True |
| isinstance(1, str) |
| False |
| isinstance(True, bool) |
| True |
| isinstance(1,(str, list, tuple, int)) |
| True |
| x = input('>>>') |
| >>> |
| print(x) |
| 123 |
print分隔符
| print(1, 2, 3, [], [1,2,3],sep='\t\t') |
| print(1, 2, 3, sep='#',end='\t') |
math 天花板地板
| print (math. ceil (1.0), math.ceil (1.3), math.ceil (1.5), math.ceil (1.6), math.ceil (1.8)) |
| 1 2 2 2 2 |
| print (math.floor (1.0), math. floor (1.3), math. floor (1.5), math. floor (1.8), math. floor (2.0)) |
| 1 1 1 1 2 |
| math.ceil (-1.0), math.ceil (-1.3), math.ceil (-1.5), math.ceil (-1.6), math.ceil (-1.8) |
| (-1, -1, -1, -1, -1) |
| math.floor (-1.0), math. floor (-1.3), math. floor (-1.5), math. floor (-1.8), math. floor (-2. 9) |
| (-1, -2 ,-2 ,-2 ,-2 ) |
int()
只截取整数部分
round()
找0.5最近的偶数,(四舍六入、0.5取偶)
数据库连接与建表
| import pymysql |
| |
| |
| conn = pymysql.connect(host='localhost', user='root', password='password', database='mydb') |
| |
| |
| cursor = conn.cursor() |
| |
| |
| cursor.execute("SHOW TABLES LIKE 'k8s_memory_7d_use'") |
| result = cursor.fetchone() |
| |
| |
| if not result: |
| cursor.execute(""" |
| CREATE TABLE k8s_memory_7d_use ( |
| id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, |
| k8s_cluster VARCHAR(50) NOT NULL, |
| namespace VARCHAR(50) NOT NULL, |
| pod VARCHAR(50) NOT NULL, |
| instance VARCHAR(50) NOT NULL, |
| memory_7d_arrive_now_max_unit_M INT(11) NOT NULL, |
| Memory_Limit_M INT(11) NOT NULL, |
| Memory_Use_percentage FLOAT(6,2) NOT NULL |
| ) |
| """) |
| print("Table k8s_memory_7d_use created successfully") |
| |
| |
| cursor.close() |
| conn.close() |
9 * 9 乘法表练习补充
python 9*9 乘法表三元表达式实现判断格式化输出
| for i in range(1,10): |
| for j in range(1,i+1): |
| print('{} * {} = {}'.format(j,i,i*j),end=' ') |
| print() |
| 再次优化 |
| for i in range(1,10): |
| for j in range(1, i+1): |
| print("{} * {} = {}".format(j, i, i*j), end=" " if j != i else "\n") |
| 再次优化 |
| for i in range(1,10): |
| for j in range(1, i+1): |
| print("{} * {} = {:<{}}".format(j, i, i*j, 2 if j == 1 else 3) ,end="" if j != i else "\n") |
| n = 7 |
| leadingchar = ' ' |
| char = '*' |
| for i in range (-3, 4): |
| spaces = -i if i < 0 else i |
| print (spaces * leadingchar, end='') |
| print ( (7 - 2 * spaces) * char) |
| |
| n = 11 |
| e = n // 2 |
| leadingchar = ' ' |
| char = '*' |
| |
| for i in range(-e,n-e): |
| print("{:^{}}".format((n - 2 * abs(i)) * char ,n)) |
| n = 13 |
| e = n // 2 |
| f = e + 1 |
| for i in range (-e, f): |
| if i < 0: |
| print(' ' * -i + (f+i) * '*') |
| elif i > 0: |
| print(' ' * e + (f - i ) * '*') |
| else: |
| print (n * '*') |
| a = 1 |
| b = 1 |
| print('index={}, fib={}'.format(0, 0)) |
| print('index={}, fib={}'.format(1,a)) |
| print('index={}, fib={}'.format(2,b)) |
| index = 2 |
| |
| while True: |
| c = a + b |
| index += 1 |
| print('index={}, fib={}'.format(index, c)) |
| if index == 101: break |
| a = b |
| b = c |
| import datetime |
| |
| start = datetime.datetime.now() |
| |
| count = 1 |
| |
| |
| |
| for x in range(3,100000,2): |
| for i in range(3, int(x ** 0.5) +1 ,2): |
| if x % i == 0: |
| break |
| else: |
| |
| count += 1 |
| delta = (datetime.datetime.now() - start).total_seconds() |
| print('count={}, time={}'.format(count, delta)) |
| |
| |
| |
| import datetime |
| |
| n = 100000 |
| |
| start = datetime.datetime.now() |
| |
| count = 2 |
| |
| primenumbers = [3] |
| |
| for i in range(5,n,2): |
| edge = int(i ** 0.5) + 1 |
| flag = False |
| |
| for j in primenumbers: |
| if j > edge: |
| break |
| if i % j == 0: |
| flag = True |
| break |
| if not flag: |
| primenumbers.append(i) |
| count += 1 |
| delta = (datetime.datetime.now() - start).total_seconds() |
| print(delta) |
| print(count) |
| |
| |
| |
| import datetime |
| |
| start = datetime.datetime.now() |
| |
| n = 1000000 |
| x =7 |
| step = 4 |
| primenumbers = [3,5] |
| count = 3 |
| |
| while x < n: |
| if x % 5 != 0: |
| edge = int(x ** 0.5) + 1 |
| flag = False |
| for i in primenumbers: |
| if i > edge: |
| flag = True |
| break |
| if x % i == 0: |
| break |
| if flag: |
| primenumbers.append(x) |
| count += 1 |
| x += step |
| step = 4 if step == 2 else 2 |
| delta = (datetime.datetime.now() - start).total_seconds() |
| print(delta,count) |
| |
| x = [] |
| |
| import sys |
| sys.getrefcount(x) |
记录vue
element-plus 错误处理
vue WEBPACK_IMPORTED_MODULE is not a function 报错处理
bytes生成字母表
| bytes(range(65, 91)) |
| b'ABCDEFGHIJKLMNOPORSTUVWXYZ' |
| bytes(range(65+0x20, 91+32)) |
| b'abcdefghijklmnopqrstuvwxyz' |
切片补充
| In [5]: aa = [0,1,2,3,4,5,6,7,8,9] |
| |
| In [6]: aa[::-1] |
| Out[6]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] |
| |
| In [7]: aa[::2] |
| Out[7]: [0, 2, 4, 6, 8] |
| |
| In [8]: aa[::-2] |
| Out[8]: [9, 7, 5, 3, 1] |
| |
| In [9]: t = [10, 50, 2, 3, 4] |
| In [10]: t[1:] = range(10,20) |
| In [11]: t |
| Out[11]: [10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] |
补充es
| |
| GET /_cluster/allocation/explain |
| |
| POST /_cluster/reroute?retry_failed=true |
| |
| GET /_cat/allocation?v |
| |
| [i for i in range(5)] |
| [list(range(5))] |
| [*range(5)] |
| 列表是可迭代对象,生成器也是可迭代对象; |
| 生成器也是迭代器一种,但列表不是; |
| 迭代器特点: |
| 1. 一次性迭代,指针不会回头 |
| 2. 类似range(range不是迭代器),是惰性,但next可以挤一下 |
| 3. for循环可以迭代,但是如果已经到头,for相当于迭代空容器但是next 不能迭代,如果使用next会抛出 StopIteration |
| [str(i) for i in range(5)] |
| [list(map(str,range[5]))] |
- 生成器表达式和列表解析式对比
- 计算方式
- 内存占用
- 单从返回值本身来说,生成吕表达式省内存,列表解析式返回新的列表;
- 生成器没有数据,内存占用极少,但用的时候,一次返回一个数据,只会战胜一个数据的空间;
- 列表解析式构造新的列表需要为所有元素立即占用掉内存;
- 计算速度
- 单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长;
- 但生成器本身并没有返回任何值,只返回了一个生成器对象;
- 列表解析式构造并返回了一个新的列表。
| sorted(dict(a=1, b='123',c=200).values(),key=str) |
| |
| |
| |
| def add(x, y) |
| |
| result = x +y |
| return result |
| ret = add(4, 5) |
| print(ret) |
| In [2]: import string |
| |
| In [3]: print(string.ascii_lowercase) |
| abcdefghijklmnopqrstuvwxyz |
| |
| In [4]: alphabet = 'abcdefghijklmnopqrstuvwxyz' |
| |
| In [5]: alphabet= "".join(chr(i) for i in range(0x61, 0x61+26)) |
| |
| In [6]: alphabet |
| Out[6]: 'abcdefghijklmnopqrstuvwxyz' |
| In [14]: for i in range(1,10): |
| ...: id = "{:0>6}.{}".format(i, '') |
| ...: print(id) |
| ...: |
| 000001. |
| 000002. |
| 000003. |
| 000004. |
| 000005. |
| 000006. |
| 000007. |
| 000008. |
| 000009. |
| def config(host,port, **kwargs) |
| print(host) |
| print(port) |
| print(kwargs) |
| config('localhost', 3306,username='test') |
- 形参
- 可以有缺省值、定义时,如果没有提供该参数,动用缺省值。缺省值的定义往后放;
- 5种
- 1普通形参: 可以有缺省值,2种传实参的方式都可以用
- 2*args 可变仅位置形参,只能接收按照位置传入的实参,可以接收0个或任意个。没有缺省值;
- 3**kwargs可变仅关键字形参,只能接收关键字传入的实参,可以接收0个或任意个。形参的最后一个,没有缺省值。
| |
| def fn(x,y=5,*args,**kwargs): |
| print(x,y,args,**kwargs) |
| fn(1),fn(x=5),fn(x=6,y=7),fn(a=7,x=10), |
运维常用函数定义方法
| def config(host,username='renjin',password='renjin', *, port=3306, **options): |
| db = options.get('db','test') |
| connstr = "mysql://{}:{}@{}:{}/{}?charset=utf8".format(username,password,host,port,db) |
| print(connstr) |
| |
| |
| config('www.asjin.com','root','testpwd',port=3397,db='cmdb') |
| |
| mysql://root:testpwd@www.asjin.com:3397/cmdb?charset=utf8 |
def config(...):
- 这是一个函数定义的开始,函数名为config,后面的括号内包含函数的参数。host
- 这是函数的第一个参数,表示要连接到的MySQL数据库的主机名或IP地址。username='renjin'
- 这是一个可选的参数,默认值为’renjin’。它表示连接数据库时要使用的用户名。如果不提供该参数,将使用默认值’renjin’。password='renjin'
- 这是另一个可选的参数,默认值也为’renjin’。它表示连接数据库时要使用的密码。如果不提供该参数,将使用默认值’renjin’。*, port=3306
- 这里的星号(*)表示从这里开始,后面的参数必须以关键字参数的方式传递,不能使用位置参数。port 是一个关键字参数,它表示要连接的MySQL数据库的端口号,默认为3306。如果提供了端口号,它将覆盖默认值。**options
- 这是一个特殊的语法,表示接受任意数量的关键字参数,并将它们存储在一个名为options的字典中。这些参数可以用于传递一些其他的配置选项,如数据库名称等。
参数解构
* 对容器解构,按照位置传实参,字典取的是key
** 只用于mapping,按照kv对实现关键字的传参,key要和形参对应起来
| '''参数解构''' |
| |
| def add(*nums): |
| s = 0 |
| for i in nums: |
| s += i |
| return s |
| |
| print(add(*[1,2]),add(*(1,2)),add(*{1,2}),add(*{'a':1,'b':2}.values())) |
| |
| '''打印结果是''' |
| |
| |
| def x(a,b): |
| return a + b |
| print(x(**{'a':100,'b':200})) |
| |
| '''打印结果是''' |
| |
一般情况下,python函数遇到return时,将不再执行剩下的语句,而立即返回;
引用函数并解构
| def fn(): |
| return 1, 3, 5 |
| |
| x, y, z = fn() |
| |
作用域: 标识符的可见范围
函数开辟了一个作用域,x被限制在了函数作用域中,对外不可见;
全局的、函数外的变量、对内穿透;全局变量、即全局可见;
全局变量也是有作用域的,只不过是全局变量、因此全局可见;
反过来,局部变量、即内部变量、只能在内部看到;
函数可以嵌套
简单的示例
| '''打印结果是''' |
| |
| def outer(): |
| o = 65 |
| def inner(): |
| print('in inner',o,chr(o)) |
| inner() |
| print('in outer',o,chr(o)) |
| |
| outer() |
| '''打印结果是''' |
| |
| |
那么以下示例的结果分析呢 ?
| def outer1(): |
| o = 65 |
| def inner(): |
| o = 97 |
| print('in inner',o,chr(o)) |
| inner() |
| print('in outer',o,chr(o)) |
| '''打印结果是''' |
| |
| |
全局变量与局部变量的坑点
| '''局部变量报错测试''' |
| z = 100 |
| def fn3(): |
| print(z) |
| m = z + 1 |
| print(m) |
| z = z + 1 |
| print(z) |
| fn3() |
| |
| |
| |
这样就可以穿透进来
| z = 100 |
| def fn2(): |
| print(z) |
| t = z + 1 |
| print(t) |
| fn2() |
| |
| |
| |
- 在函数中
global z
声明z不再是局部变量,而是全局变量;
- 全局变量,如果所有函数都是用的全局变量,但是局部作用域就没有用了,全局变量污染了。
- 全局变量也是有作用域的,只不过是全局的,所以全局可见;
- 全局变量一般都是公用的,一般情况下不要修改;
- 函数中形参一定是局部变量
- 函数使用全局变量,一定要使用传参,而不是使用穿透;
Faas Sass Iaas Pass
闭包
| def inc(): |
| c = [0] |
| def inner(): |
| c[0] += 1 |
| return c[0] |
| return inner |
| |
| foo = inc() |
| print(1,foo()) |
| print(2,foo()) |
| |
| |
| |
| |
| |
函数的销毁
- 定义一个函数就是生成一个函数的对象,函数名指向的就是函数对象;
- 可以使用del语句删除函数,使其引用计数减1;
- 可以使用同名标识符覆盖原有定义,本质上也是使用其引用计数减1;
- Python程序结束时,所有对象销毁;
- 函数也是对象,也不例外,是否销毁,还是看引用计数是否减为0;
变量名解析原则LEGB*
- local,本地作用域、局部作用域的local命名空间。函数调用时创建,调用结束消亡;
- Enclosing, Python2.2时引入了嵌套函数,实现了闭包,这个就是嵌套函数的外部函数的命名空间;
- Global,全局作用域名,即一个模块的命名空间。模块被import时创建,解释器退出时消亡;
- build-in,内置模块的命名空间,生命周期从python解释器容器启动时创建到解释器退出时消亡。例如print(open),print和open都是内置的变量;
匿名函数
| (lambda *args: [i+1 for i in args])(*range(10)) |
| |
| (lambda *args: {i%3 for i in args})(*range(10)) |
| |
| dict(map(lambda x: (x,x**2),range(10))) |
| |
| |
| ",".join(map(str,range(10))) |
| |
| |
| {str(i):i+1 for i in range(10)} |
| |
需求 我要一个字典,kv对,key对应的value必须是列表
| d1 = {k:[] for k in 'abcde'} |
| print(d1) |
| d1['a'].append(1) |
| print(d1) |
| |
| |
| d1 = dict(map(lambda x: (x,[]),'abcde')) |
| print(d1) |
| d1['a'].append(1) |
| print(d1) |
| |
| |
| d1 = dict.fromkeys('abcde',[]) |
| print(d1) |
| d1['a'].append(1) |
| print(d1) |
| |
| |
| |
| |
| from collections import defaultdict |
| d2 = defaultdict(lambda: {100}) |
| print(d2['m']) |
| print(d2) |
| |
| |
| |
| |
| |
| In [1]: (lambda *args: [i+1 for i in args])(*range(5)) |
| Out[1]: [1, 2, 3, 4, 5] |
| |
| In [2]: (lambda *args: list((i+1 for i in args)))(*range(5)) |
| Out[2]: [1, 2, 3, 4, 5] |
| |
| In [3]: dict(map(lambda x:(str(x), x+1), range(5))) |
| Out[3]: {'0': 1, '1': 2, '2': 3, '3': 4, '4': 5} |
比如正常代码中的一些需求、需一个字典、kv对,key对应的value必须是列表
| In [4]: d1 = dict(map(lambda x: (x,[]), 'abcde')) |
| In [5]: d1 |
| Out[5]: {'a': [], 'b': [], 'c': [], 'd': [], 'e': []} |
| |
| |
| |
| In [6]: d1 = {k:[] for k in 'abcde'} |
| In [7]: d1 |
| Out[7]: {'a': [], 'b': [], 'c': [], 'd': [], 'e': []} |
| |
| x = ['a',1,'b',20,'c',32] |
| def fn(x): |
| return x if isinstance(x,int) else int(x,16) |
| |
| print(sorted(fn(x=x)) |
| |
| print(sorted(x,key=lambda x: x if isinstance(x,int) else int(x,16))) |
生成器函数
生成器对象:
- 生成器表达式,每一次生成器表达式执行一次都会得到一个全新的生成器对象;
- 生成器函数,每一次函数调用都会得到全新的生成器对象。只要有yield语句的函数都是生成器函数;
- 生成器函数,每一次执行到yield这一句,把yield的值返回;
- return非常强势,见到它函数就完成执行了、如果你用next驱动生成器对象,碰到了return,抛出StopIteration异常,用for就不会因为for循环会友好的退出;
- 生成器函数惰性本身是推荐的,还有他用在了协程中,线程、进程之后;
| |
| def generate_numbers(n): |
| for i in range(n): |
| yield i |
| |
| my_generate = generate_numbers(5) |
| |
| for number in my_generate: |
| print(number) |
| |
| '''以上代码,使用yield关键字,将函数变成了一个生成器,每次调用next()方法,就会执行一次函数,并返回一个值,直到函数执行完毕,抛出StopIteration异常,表示生成器执行完毕'' |
| |
应用
所以生成器函数元素可以是有限个对象、也可以是无限个;
| '''生成器函数无限容器,可作用为id生成器''' |
| def foo(): |
| count = 0 |
| while True: |
| count += 1 |
| yield count |
| |
| my_foo = foo() |
| |
| for i in my_foo: |
| print(i) |
| print('\n') |
| if i > 100: |
| break |
| '''计数器''' |
| def inc(): |
| def foo(): |
| count = 0 |
| while True: |
| count += 1 |
| yield count |
| c = foo() |
| return c |
| |
| x = inc() |
| print(next(x)) |
| print(next(x)) |
| |
| '''方法二''' |
| def inc(): |
| def foo(): |
| count = 0 |
| while True: |
| count += 1 |
| yield count |
| c = foo() |
| return lambda : next(c) |
| |
| x = inc() |
| print(x()) |
| print(x()) |
yield 方法简写
| def foo(): |
| yield from range(10) |
| |
| for x in foo(): |
| print(x) |
| |
| '''以上等同于''' |
| |
| def foo(): |
| for i in range(10): |
| yield i |
| |
| for x in foo(): |
| print(x) |
| |
| '''yield from 语法,可以将一个生成器,转换成一个迭代器,并且将生成器中的值,全部返回''' |
| def foo(): |
| yield from map(lambda x: x+100 , range(10)) |
| |
| for x in foo(): |
| print(x) |
| test_dict = dict(map(lambda x,y: (x, y+100), 'abcde', range(10))) |
| print(test_dict) |
高阶函数;
| def counter(base): |
| def inc(step=1): |
| nonlocal base |
| base += step |
| return base |
| return inc |
| |
| f = counter(100) |
| print(f(10)) |
| print(f(10)) |
| |
| |
| '''柯里化''' |
| |
| def add(x): |
| def fn(y): |
| return x + y |
| return fn |
| |
| print(add(10)(20)) |
加wraps
| from functools import wraps |
| def logger(fn): |
| @wraps(fn) |
| def inner(*args,**kwargs): |
| ''' |
| add description |
| 这个warpper函数的描述 |
| ''' |
| print(fn.__name__,args,kwargs) |
| print('执行前可以做的事情,增强') |
| ret = fn(*args,**kwargs) |
| print('执行后可以做的事情,增强') |
| return ret |
| return inner |
| logger_add = logger(add)(4,y=100) |
| print(logger_add) |
| |
| |
| @logger |
| def add(x,y:int): |
| ''' |
| add description |
| 这add函数的描述 |
| ''' |
| return x + y |
| |
| print(add.__name__, add.__doc__, add.__annotations__) |
| |
| add (4,) {'y': 100} |
| 执行前可以做的事情,增强 |
| 执行后可以做的事情,增强 |
| 104 |
| add |
| add description |
| 这add函数的描述 |
| {'y': <class 'int'>} |