文章目录
- python
- 变量
- 字符串
- 列表
- 元组
- 字典
- 正则表达式
- \W*和\W+匹配
- try/except
- try/finally
- `self`
- `__init__()`
- `__class__.__name__`
- 关键字
- nonlocal
- global
- with
- *args 和**kwargs
- [-1]、[:-1]、[::-1]、[n::-1]
- `.`
- f 和format - 字符串格式化
- r - 字符串禁止转义
- python内置类属性
- 函数中初始化传参
- python对象销毁(垃圾回收)
- 类的继承
- object基类
- pip
- 模块
- logging
- 函数
- map
- super
- readlines
- subprocess.getstatusoutput
- re.sub
- getattr
- callable
- 方法重写
- 基础重载方法
- 运算符重载
- 类属性与方法
- 类的方法
- 类的私有方法
- 单下、双下、头尾双下划线
- 闭包&LEGB法则
- @修饰符
- 生成器和迭代器
- 生成器和迭代器的区别
- 实现原理
- !#/usr/bin/env python 和 !#/usr/bin/python
python
变量
- 使用类内的全局变量
- 可以将变量定义在
__init__
中
#!/usr/bin/python3
import time
class ProcessState():
def __init__(self):
self.state = 10
def deal_with(self):
print("deal with process state=%d" % self.state)
self.state += 1
if __name__ == "__main__":
print("main running")
p = ProcessState()
p.deal_with()
p.deal_with()
p.deal_with()
p.deal_with()
字符串
- 访问字符串的值
- Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。
Python 访问子字符串,可以使用方括号 [] 来截取字符串,字符串的截取的语法格式如下:变量[头下标:尾下标]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QFXGvEEB-1661061111459)(C:\Users\11639\AppData\Roaming\Typora\typora-user-images\image-20220415144029189.png)]
- join方法
- Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串
str.join(sequence)
- 参数
- sequence – 要连接的元素序列
- 返回值
- 返回通过指定字符连接序列中元素后生成的新字符串
str = "-"
seq1 = ("a", "b", "c")
seq2 = ["1", "2", "3"]
print(str.join(seq1))
print(str.join(seq2))
a-b-c
1-2-3
- strip方法
- str.strip([chars])
- 参数
- chars – 移除字符串头尾指定的字符序列
- 返回值
- 返回移除字符串头尾指定的字符生成的新字符串
str = "00000003210Runoob01230000000";
print str.strip( '0' ); # 去除首尾字符 0
str2 = " Runoob "; # 去除首尾空格
print str2.strip();
- upper方法
- Python upper() 方法将字符串中的小写字母转为大写字母
- startswith
- 判断字符串是不是以指定字符串开头的,如果是,返回True,否则,返回False
- 参数
- str – 检测的字符串。
- strbeg – 可选参数用于设置字符串检测的起始位置。
- strend – 可选参数用于设置字符串检测的结束位置。
列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7fsCJD6N-1661061111460)(C:\Users\11639\AppData\Roaming\Typora\typora-user-images\image-20220407113917599.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a4oxPlrD-1661061111461)(C:\Users\11639\AppData\Roaming\Typora\typora-user-images\image-20220407113935940.png)]
- [ ]
list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]
- 访问列表的值
#!/usr/bin/python
list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5, 6, 7 ]
print("list1[0]: ", list1[0])
print("list2[1:5]: ", list2[1:5])
- 使用列表做判断
if (2 in [2, 3, 4])
print("find this number")
- list之间的差异、相同
listA = [‘zhangsan’, ‘lisi’, ‘wangwu’]
listB = [‘zhangsan’, ‘lisi’, ‘zhaoliu’]
- listA对应listB的差集
set(listA).difference(set(listB))
[‘wangwu’]
- listB对应listA的差集
set(listB).difference(set(listA))
[‘zhaoliu’]
- listA对应listB取交集
set(listA).intersection(set(listB))
[‘zhangsan’, ‘lisi’]
- listA对应listB取并集
set(listA).union(set(listB))
[‘lisi’, ‘zhangsan’, ‘wangwu’, ‘zhaoliu’]
- 二维列表
- python 创建List二维列表
lists [ [] for i in range(2) ] #创建多行三列的二维列表
for i in range(3):
lists[0].append(i)
for i in range(5):
lists[1].append(5)
for i in range(7):
lists[2].append(i)
print ("lists is:", lists)
- python 二维列表索引遍历二维列表
sum_0 = 0
for i in range(len(lists)):
for j in range(len(lists[i])):
print(lists[i][j])
sum_0 += lists[i][j]
print("The sum_0 of Lists:", sum_0)
元组
- Python 的元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。 - 基本用法
tup1 = ('physics', 'chemistry', 1997, 2000) tup2 = (1, 2, 3, 4, 5, 6, 7 ) print "tup1[0]: ", tup1[0] print "tup2[1:5]: ", tup2[1:5]
- 把元组当作二维数组来用
opts = [("grpc.keepalive_time_ms", 120000),
("grpc.keepalive_timeout_ms", 60000),
("grpc.keepalive_permit_without_calls", True),
("grpc.http2.max_ping_strikes", 0)]
# print(opts[0][0])
# print(opts[1][0])
# print(opts[2][0])
for name in opts:
print(name[0])
字典
- { }
- 字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
if __name__=='__main__':
tinydict = {}
tinydict['name'] = "xiaoming"
tinydict['year'] = 12
tinydict['height'] = 180
print(tinydict['name'])
print(tinydict['year'])
print(tinydict['height'])
$python3 main.py
xiaoming
12
180
- items
dict.item()
字典(Dictionary) items() 函数以列表返回可遍历的(键, 值) 元组数组。
tinydict = {'Google':'www.google.com', 'taobao':'www.taobao.com'}
print("字典值:%s" % tinydict.items())
for key,values in tinydict.items():
print("key=%s, value=%s" % (key, values))
$python3 main.py
字典值:dict_items([('Google', 'www.google.com'), ('taobao', 'www.taobao.com')])
key=Google, value=www.google.com
key=taobao, value=www.taobao.com
正则表达式
规范 | 描述 |
| 表示反斜线 |
| 表示换行 |
| 除了a、b、c |
| 表示数字 |
| 表示字母、数字、下划线 |
| 表示所有空白字符(换行、空格等) |
| 表示制表符 |
| 表示字符a、b或c |
| 表示由字母、数字组成 |
| 表示非数字 |
| 表示非字母、数字、下划线 |
| 表示所有非空白字符 |
| 比如W后有了+,X内的字符可以取任意多个。于是[]内的字符可以以任意次序出现任意多次,直到遇到第一个非[]内的字符。如[AB]+ 既可以匹配AAABBB又可以匹配BBBAAA BABAAABA等,不是一定要A…B…的次序 |
\W*和\W+匹配
- \W*原理分析:
re.split('\W*','Hello,world')
['', 'H', 'e', 'l', 'l', 'o', '', 'w', 'o', 'r', 'l', 'd', '']
re.split('(\W*)','Hello,world')
['', '', 'H', '', 'e', '', 'l', '', 'l', '', 'o', ',', '', '', 'w', '', 'o', '', 'r', '', 'l', '', 'd', '', '']
- **\W+**原理分析:
re.split('\W+','Hello,world')
['Hello', 'world']
re.split('(\W+)','Hello,world')
['Hello', ',', 'world']
try/except
- 异常处理
- 捕捉异常可以使用此语句,用来检测try语句块中的错误,从而让except语句捕捉到异常信息并处理
- 如果你不想在异常发生时结束你的程序,只需在try里捕捉它
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
print "Error: 没有找到文件或读取文件失败"
else:
print "内容写入文件成功"
fh.close()
try/finally
- 无论try里面做了什么,即使是return,也会调用finally
def f():
try:
print 1
return 1
finally:
print 0
print f()
# 执行顺序:先执行try中print 1,然后执行finally中print 0,最后执行print f()-->return 0, 所以打印为1 0 1
$python3 main.py
1
0
1
self
- 代表类的实例,而非类
- 代表当前对象的地址
self.__class__
则指向类
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
- 类的方法与普通函数只有一个特别区别
- 类必须有一个额外的第一个参数名称,按照惯例称为==self==
- self不属于python的关键字,我们把它换为anything也是可以正常执行
class Test:
def prt(runoob):
print(runoob)
print(runoob.__class__)
t = Test()
t.prt()
__init__()
- 创建实例对象
实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式。
以下使用类的名称 Employee 来实例化,并通过 init 方法接收参数。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Employee:
'所有员工的基类'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount
- 父子调用
__init__
三种情况:
- 子类仅需要自动调用父类的构造方法,而子类自身不需要构造方法:子类不重写
__init__
,实例化子类后,会自动调用父类的__init__()
的方法 - 子类不需要自动调用父类的构造方法,而子类自身需要构造方法:子类重写
__init__
,实例化子类后,会自动调用子类的__init__()
的方法,而不调用父类的__init__()
- 子类重写
__init__()
方法又需要父类的构造方法:使用super关键词
super(子类,self).__init__(参数1,参数2,....)
class Son(Father):
def __init__(self, name):
super(Son, self).__init__(name)
#!/usr/bin/python3
class Father:
print("i am father")
class Son(Father):
def __init__(self):
Father.__init__(self)
print("i am son")
if __name__=='__main__':
son = Son()
i am father
i am son
__class__.__name__
- 获取当前类名
self.__class__.__name__
关键字
nonlocal
- nonlocal 用来声明外部函数的局部变量
global
- global用来声明全局变量
a = 100
def outer():
b = 10
def inner():
nonlocal b # 声明外部函数的局部变量
print(r"inner b:", b)
b = 20
global a # 声明全局变量
a = 1000
inner()
print(r"outer b:", b)
outer()
print("a :" ,a)
输出:
inner b: 10
outer b: 20
a : 1000
with
- 什么是with语句?
- 有一些任务,可能事先需要设置事后清理工作,所以with能够执行自动清除的工作
__exit__
- 例如获取一个文件句柄,从文件中读取数据,然后关闭文件句柄
- with使用怎么工作的?
- 基本思想是:with所求值的对象必须有一个enter()方法,一个exit()方法
*args 和**kwargs
- *args
def fun_var_args(farg, *args):
print("arg:", farg)
for value in args:
print("another arg:", value)
fun_var_args(1, "two", 3) # *args可以当作可容纳多个变量组成的list
arg:1
another arg:two
another arg:3
- *kwargs
def fun_var_kwargs(farg, *args, **kwargs):
print("arg:", farg)
for value in args:
print("another arg:", value)
for key in kwargs:
print("another keyword arg:%s:%s" % (key, kwargs[key]))
fun_var_kwargs(1, myarg1="two", myarg2=3) # myarg1和myarg2被视为key,**kwargs可以容纳多个key和value的dictionary
arg: 1
another keyword arg: myarg2: two
another keyword arg: myarg3: 3
[-1]、[:-1]、[::-1]、[n::-1]
import numpy as np
a=np.random.rand(5)
print(a)
[ 0.64061262 0.8451399 0.965673 0.89256687 0.48518743]
print(a[-1]) ###取最后一个元素
[0.48518743]
print(a[:-1]) ### 除了最后一个取全部
[ 0.64061262 0.8451399 0.965673 0.89256687]
print(a[::-1]) ### 取从后向前(相反)的元素
[ 0.48518743 0.89256687 0.965673 0.8451399 0.64061262]
print(a[2::-1]) ### 取从下标为2的元素翻转读取
[ 0.965673 0.8451399 0.64061262]
.
- 访问属性
您可以使用点号 . 来访问对象的属性。使用如下类的名称访问类变量:
```
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
```
f 和format - 字符串格式化
- 格式化的字符串文字前缀为’f’与’str.format()'相似,它们包含由花括号包围的替换区域。替换字段是表达式或变量,在运行时进行评估,然后使用format()协议进行格式化。以 f 开头,包含的{}表达式在程序运行时会被表达式的值代替。
print(f'{name}')
其中 { } 相当于占位符,程序运行时花括号部分会变成相应的变量值,如果print('{name}')
中 f 被去掉,就是普通的打印功能,原封不动地打印字符串 {name}.format
,格式化字符串,与f
的含义类似,示例如下:
#!/usr/bin/python3
base_dir = '/sys/devices/system/node/node'
nmid = 1234
hpages_dir = '{}{}{}.format(base_dir, str(nmid), '/hugepages/')'
output:/sys/devices/system/node/node1234/hugepages/
r - 字符串禁止转义
在打开文件的时候open(r’c:…')
加r和不加r是有区别的
'r'
是防止字符转义的 如果路径中出现'\t'
的话 不加r
的话\t
就会被转义 而加了'r'
之后'\t'
就能保留原有的样子
在字符串赋值的时候 前面加’r’可以防止字符串在时候的时候不被转义 原理是在转义字符前加'\'
s = r'\tt'
print(s)
Output:
'\tt'
s ='\tt'
print(s)
Output:
' t'
python内置类属性
- dict : 类的属性(包含一个字典,由类的数据属性组成)
- doc :类的文档字符串
- name:类的文档字符串
- module: 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块mymod中,那么className.module 等于 mymod)
- bases : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
函数中初始化传参
- id=-1,如果函数没有传入id参数,该参数默认设置为-1,如果传入id参数,则使用传入的参数
def state_conter(value, id=-1):
try:
itself_id = id + 1
if (value in [3, 8]):
print("value in [3, 8]")
print("itself id: %d, %d" % (value, itself_id))
except:
print("error!!!!!!!")
if __name__=='__main__':
state_conter(123, 4)
state_conter(456)
$python3 main.py
itself id: 123, 5
itself id: 456, 0
python对象销毁(垃圾回收)
Python 使用了引用计数这一简单技术来跟踪和回收垃圾。
在 Python 内部记录着所有使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。
class Point:
count = 0
def __init__(self, a = 0, b = 0):
self.a = a
self.b = b
Point.count += 1
def __del__(self):
class_name = self.__class__.__name__
print(class_name, "销毁")
if __name__ == '__main__':
print("module running")
t1 = Point()
t2 = t1
t3 = t1
print(t1.count)
del t1
del t2
del t3
else:
print("module loading")
类的继承
面向对象的变成带来的主要好处之一是代码重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类
- 继承语法
class 派生类名(基类名)
...
- python继承中的特点
- 如果在子类中需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法。
- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数。
- Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
#!/usr/bin/python3
class Parent:
parentAttr = 100
def __init__(self):
print("调用父类构造函数")
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print("父类属性:", Parent.parentAttr)
def __del__(self):
print("调用父类析构函数")
class Child(Parent):
def __init__(self):
print("调用子类构造方法")
def childMethod(self):
print("调用子类方法")
def __del__(self):
print("调用子类析构函数")
if __name__ == '__main__':
print("module running")
c = Child()
c.childMethod()
c.setAttr(20000)
c.getAttr()
else:
print("module loading")
```
$python3 main.py
module running
调用子类构造方法
调用子类方法
父类属性: 20000
```
使用基类中的方法时,不会自动调用基类中的构造函数
- 子类要调用父类中的构造函数:
子类不重写 init,实例化子类时,会自动调用父类定义的 init
class Father(object):
def __init__(self, name):
self.name=name
print ( "name: %s" %( self.name) )
def getName(self):
return 'Father ' + self.name
class Son(Father):
def getName(self):
return 'Son '+self.name
if __name__=='__main__':
son=Son('runoob')
print ( son.getName() )
- 多重继承语法
class SubClassName (ParentClass1[, ParentClass1, ParentClass2, ...])
- 如果在继承元组中列了一个以上的类,那么它就被称作“多重继承”
object基类
>>> int.__bases__ # 查看int类的基类,结果为int类是继承自object类的
(<class 'object'>,)
>>> str.__bases__ # 查看str类的基类,结果为str类是继承自object类的
(<class 'object'>,)
>>> tuple.__bases__ # 查看tuple类的基类,结果为tuple类是继承自object类的
(<class 'object'>,)
>>> list.__bases__ # 查看list类的基类,结果为list类是继承自object类的
(<class 'object'>,)
>>> dict.__bases__ # 查看dict类的基类,结果为dict类是继承自object类的
(<class 'object'>,)
>>> set.__bases__ # 查看set类的基类,结果为set类是继承自object类的
(<class 'object'>,)
object基类是所有类型的基类
pip
- pip是Python包的管理工具,该工具提供了对Python 包的查找、下载、安装、卸载的功能。
- 注意:Python 2.7.9 + 或 Python 3.4+ 以上版本都自带 pip 工具。
- 缺什么库可以装什么库
- 示例:pip3 install service**当使用service库的时候**
模块
logging
- 简介
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
- 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息
- print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出
Logger从来不直接实例化,经常通过logging模块级方法(Module-Level Function)logging.getLogger(name)来获得,其中如果name不给定就用root。
名字是以点号 分割的命名方式命名的(a.b.c)。对同一个名字的多个调用logging.getLogger()方 法会返回同一个logger对象。这种命名方式里面,后面的loggers是前面logger的子 logger,自动继承父loggers的log信息,正因为此,没有必要把一个应用的所有 logger都配置一遍,只要把顶层的logger配置好了,然后子logger根据需要继承就行了。
logging.Logger对象扮演了三重角色:
* 暴露给应用几个方法以便应用可以在运行时写log.
* ,Logger对象按照log信息的严重程度或者根据filter对象来决定如何处理log信息(默认的过滤功能).
* logger还负责把log信息传送给相关的handlers.
- 基本用法
- 配置logging基本的设置,然后在控制台输出日志
import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
1 2016-10-09 19:11:19,434 - __main__ - INFO - Start print log
2 2016-10-09 19:11:19,434 - __main__ - WARNING - Something maybe fail.
3 2016-10-09 19:11:19,434 - __main__ - INFO - Finish
logging中可以选择很多消息级别,如:DEBUG,INFO,WARNING,ERROR,CRITICAL,通过赋予logger或者handler不同的级别,开发者就可以只输出错误信息到特定的记录文件,或者在调试时只记录调试信息
- logger的级别改为DEBUG或其他输出级别,不同输出级别打印的内容也不同
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- 函数含义
- logging.basicConfig函数各参数:
- filename:指定日志文件名;
- filemode:和
file
函数意义相同,指定日志文件的打开模式,'w'
或者``‘a’;
- format
:指定输出的格式和内容,
format``可以输出很多有用的信息
- datefmt:指定时间格式,同time.strftime()
- level:设置日志级别,默认为logging.WARNNING
- stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
函数
map
- map() 会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。 - 语法
map(function, iterable, ...)
- 参数
- function – 函数
- iterable – 一个或多个序列
- 返回值
- Python 2.x 返回列表
- Python 3.x 返回迭代器
>>> def square(x) : # 计算平方数
... return x ** 2
...
>>> map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
<map object at 0x100d3d550> # 返回迭代器
>>> list(map(square, [1,2,3,4,5])) # 使用 list() 转换为列表
[1, 4, 9, 16, 25]
>>> list(map(lambda x: x ** 2, [1, 2, 3, 4, 5])) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
>>>
D_STATE_ALARM_MSG = "d state process alarm: pidlist: %s\n"
content = D_STATE_ALARM_MSG % (','.join(map(str, self.d_state)))
print(content)
super
如果重写了__init__
时,要继承父类的构造方法,可以使用super
关键字:
super(子类, self).__init__(参数1, 参数2, ...)
另经典写法:
父类名称.__init__(self,参数1,参数2, ...)
#!/usr/bin/python3
class Father(object):
def __init__(self, name):
self.name = name
print("Father name %s" % self.name)
def getName(self):
return 'Father'+self.name
class Son(Father):
def __init__(self, name):
super(Son, self).__init__(name)
print("hi")
self.name = name
def getName(self):
return 'Son'+self.name
if __name__=='__main__':
son = Son('test')
print(son.getName())
$python3 main.py
Father name test
hi
Sontest
readlines
- readlines() 方法用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。
如果碰到结束符 EOF 则返回空字符串。 - 参数
无。
- 返回值
返回列表,包含所有的行
subprocess.getstatusoutput
subprocess.getstatusoutput | python3 获得shell的输出内容默认通过os.system(“shell")命令赋值,结果是0之类的,0表示shell命令运行正确 |
如果想获得shell输出的内容,可以通过【subprocess.getstatusoutput】获得shell返回结果 | |
示例代码 | `import subprocess PIDS=subprocess.getstatusoutput('ps -ef |
re.sub
- 匹配字符或字符串,可以字符串中替换字符
- 函数原型及含义
def sub(pattern, repl, string, count=0, flags=0):
"""Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable;
if a string, backslash escapes in it are processed. If it is
a callable, it's passed the match object and must return
a replacement string to be used."""
return _compile(pattern, flags).sub(repl, string, count)
- pattern:该参数表示正则中的模式字符串
- repl:该参数表示要替换的字符串(即匹配到pattern后替换为repl),也可以是个函数
- string:该参数表示要被处理(查找替换)的原始字符串
- count:可选参数,表示是要替换的最大次数,而且必须是非负整数,该参数默认为0,即所有的匹配都会被替换
- flags:可选参数,表示编译时用的匹配模式(如忽略大小写、多行模式等),数字形式,默认为0
import re
s = 'asdfs123asdad'
new = re.sub(r'[0-9]', '*', s)
print(new)
output: asdfs***asdad
getattr
- 描述
- getattr() 函数用于返回一个对象属性值。
- 语法
- getattr(object, name[, default])
- 参数
- object – 对象。
- name – 字符串,对象属性。
- default – 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
- 返回值
- 返回对象属性值
- 实例
>>>class A(object):
... bar = 1
...
>>> a = A()
>>> getattr(a, 'bar') # 获取属性 bar 值
1
>>> getattr(a, 'bar2') # 属性 bar2 不存在,触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'bar2'
>>> getattr(a, 'bar2', 3) # 属性 bar2 不存在,但设置了默认值
3
>>>
callable
- 描述
- callable函数用于检查一个对象是否可调用。如果返回True,object仍然可能调用失败;如果fan’huiFalse,调用对象object绝不会调用成功
- 语法
- callable(object)
- 参数
- object – 对象
- 返回值
- 可调用返回True,否则返回False
- 实例
>>>callable(0)
False
>>> callable("runoob")
False
>>> def add(a, b):
... return a + b
...
>>> callable(add) # 函数返回 True
True
>>> class A: # 类
... def method(self):
... return 0
...
>>> callable(A) # 类返回 True
True
>>> a = A()
>>> callable(a) # 没有实现 __call__, 返回 False
False
>>> class B:
... def __call__(self):
... return 0
...
>>> callable(B)
True
>>> b = B()
>>> callable(b) # 实现 __call__, 返回 True
True
方法重写
- 如果你的父类方法的功能不能满足你的需求,你可以在子类重写你的父类方法:
#!/usr/bin/python
class Parent: #定义父类
def myMethod(self):
print('调用父类方法')
class Child(Parent): #定义子类
def myMethod(self):
print('调用子类方法')
if __name__=='__main__':
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
$python3 main.py
调用子类方法
基础重载方法
__init__(self [,args...])
- 构造函数:简单的调用方法: obj = className(args)
__del__(self)
- 析构方法:删除一个对象
简单的调用方法 : del obj
__repr__(self)
- 转化为供解释器读取的形式
简单的调用方法 : repr(obj)
__str__(self)
- 用于将值转化为适于人阅读的形式
简单的调用方法 : str(obj)
__cmp__(self, x)
- 对象比较
简单的调用方法 : cmp(obj, x)
运算符重载
Python同样支持运算符重载,实例如下:
#!/usr/bin/python3
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b)
if __name__=='__main__':
v1 = Vector(1, 2)
v2 = Vector(4, -2)
print (v1 + v2)
$python3 main.py
Vector (5, 0)
类属性与方法
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs
类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)
print(counter.__secretCount) # 报错,实例不能访问私有变量
1
2
2
Traceback (most recent call last):
File "test.py", line 17, in <module>
print counter.__secretCount # 报错,实例不能访问私有变量
AttributeError: JustCounter instance has no attribute '__secretCount'
Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性,参考以下实例
$python3 main.py
www.baidu.com
单下、双下、头尾双下划线
-
__foo__
: 定义的是特殊方法,一般是系统定义名字 ,类似**__init__()**
之类的。 -
_foo
: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于from module import *
-
__foo
: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
闭包&LEGB法则
- 闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象。
- Local - 本地函数(show_filename)内部,通过任何方式赋值的,而且没有被global关键字声明为全局变量的filename变量;
- Enclosing - 直接外围空间(上层函数wrapper)的本地作用域,查找filename变量(如果有多层嵌套,则由内而外逐层查找,直至最外层的函数);
- Global - 全局空间(模块enclosed.py),在模块顶层赋值的filename变量;
- Builtin - 内置模块(builtin)中预定义的变量名中查找filename变量;
在任何一层先找到了符合要求的filename变量,则不再向更外层查找。如果直到Builtin层仍然没有找到符合要求的变量,则抛出NameError异常。这就是变量名解析的:LEGB法则。
@修饰符
- 一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。
- 本质上讲,装饰符@类似于[回调函数,把其它的函数(暂且称为目的参数)作为自己的入参,在目的函数执行前,执行一些自己的操作,比如:计数、打印一些提示信息等,然后返回目的函数。下面列举一个简单的例子
- 实例1
def test(func):
print("a")
return func()
@test# 从这里可以看出@test等价于 test(xxx()),但是这种写法你得考虑python代码的执行顺序
def xxx():
print('Hello world!')
输出结果:
a
Hello world!
- 实例2
def addspam(fn):
def new(*args):
print "spam,spam,spam"
return fn(*args)
return new
@addspam
def useful(a,b):
print a**2+b**2
- @addspam装饰器,相当于执行了useful = addspam(useful)。在这里题主有一个理解误区:传递给addspam的参数,是useful这个函数对象本身,而不是它的一个调用结果;
- 再回到addspam函数体:
- return new 返回一个闭包,fn被封存在闭包的执行环境中,不会随着addspam函数的返回被回收;
- 而fn此时是useful的一个引用,当执行return fn(*args)时,实际相当于执行了return useful(*args);
生成器和迭代器
生成器和迭代器的区别
- 生成器的好处是延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大数据量处理,将会非常有用。
- 迭代:当创建的对象可以被一个接一个读取里面的值,叫迭代。列表、元组、字典、字符串都是可迭代对象。数字、布尔值是不可迭代的对象。
- 迭代器协议:对象需要提供next()方法,通过它返回迭代中的下一项,直到返回终止抛出StopIteration异常。
- 可迭代对象:实现了迭代器协议对象。list、tuple、dict都是可迭代对象(Iterable),但不是迭代器对象(Iterator)。
需要使用内建函数iter(),把这些都变成可迭代器对象(Iterable)。 - for item in Iterable:循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法,
来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
实现原理
- 迭代器
iter
- 迭代器:Python中一个实现_iter_方法和_next_方法的类对象,就是迭代器。
>>> list = [1,2,3]
>>> lt = iter(list)
>>> print(next(lt))
1
>>> print(next(lt))
2
>>> print(next(lt))
3
>>> print(next(lt))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
- 生成器
yield
- 生成器:本质上是动态生成迭代的值,使用完直接丢弃,可以有效节省内存空间,但这些值只能被迭代一次。
>>> def g():
... for i in range(3):
... yield i
...
>>> g = g()
>>> next(g)
0
>>> next(g)
1
>>> next(g)
2
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
生成器是一种惰性的序列,如果我们需要创建一个 0~xxxxxxxxx 的序列,这样大的序列创建出来会占用内存,生成器就解决这样的问题 。
yield语句与return语句一样,都起到返回的作用。但yield与return不同,如果执行return语句,直接返回return后面表达式的值。但执行yield语句,返回的是一个生成器对象,而且这个生成器对象的当前值,就是yield语句后面跟的表达式的值。调用yield语句后,当前函数就会返回一个迭代器,而且函数会暂停执行,直到对该函数进行下一次迭代。
!#/usr/bin/env python 和 !#/usr/bin/python
当你执行 env python
时,它其实会去 env | grep PATH
里(也就是 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin )这几个路径里去依次查找名为python的可执行文件。
找到一个就直接执行,上面我们的 python 路径是在 /usr/bin/python
里,在 PATH
列表里倒数第二个目录下,所以当我在 /usr/local/sbin
下创建一个名字也为 python 的可执行文件时,就会执行 /usr/bin/python