套接字编程:
1、 函数的功能基本和c类似,唯一不同的地方在于当发生错误时,它不是通过返回值来告知的,而是通过触发异常,所以udp中的bind, recvfrom, sendto必须要进行捕捉异常。
2、 套接字在垃圾收集的时候也会关闭。
3、 获取网卡的IP:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0X8915, struct.pack('256s', ethname[:15]))[20:24])
字符串的使用:
1、 Python的字符串是不可以改变的。但是你可以操作字符串以形成新的字符串。
2、 字符串中删除一个字串。没有直接提供这个方法,但是replace可以实现:
"abc def".replace(" ", "")
同样的功能还有一个方法:translate。它的原有作用是将字符串中的某个字符替换为另外一个字符,注意,不是字符串。它的第一个参数是一个转换表。第二个参数是要删除的字符串。我们可以利用第二个参数del,实现这个功能。同时,第一个参数设置为None。
translate可能更高效一点。另外,它的第二个参数可以使一个字符串,含有多个字符,这样就会删除多个。
注意:translate方法不会对这个字符串操作,而是返回一个新的字符串。
3、 strip方法:去除字符串两侧的空格,返回新的字符串。这个功能非常有用。
4、 str中有一个函数,format,非常强大,有时间一定要看一下。
5、 endswitch:检查字符串是否已某字符串结尾。startswith:检查是否已某字符串开头。
6、 partition:它将字符串按指定的字符串分为三个部分,返回一个元组。第一个是指定字符串前面内容,第二个是指定字符串,第三个是指定字符串后面的内容。用于字符串解析非常好用。
7、 split:将字符串按照某指定字符串分割成多个子字符串,返回一个分割后的列表。
8、 join:将一个字符串列表中的各个字符串连接起来,中间插入指定的字符串。
9、 find的返回值不是false和true,所以不可以直接用于if判断。需要判断if s.find(‘’) >= 0:
10、 基于字典的格式化:
a) sh = '''
b) python -m compileall -fl ../src;
c) python -m compileall -fl ../src/micbase;
d) mkdir %(packname)s;
e) mdkir %(packname)s;
f) ''' % {'packname':sys.argv[1], }
g) print(sh)
h)
内建函数:
string.capitalize()
把字符串的第一个字符大写
string.center(width)
返回一个原字符串居中,并使用空格填充至长度 width 的新串
string.count(str, beg=0, end=len(string))
返回 str 在 string 里面出现的次数,如果 beg 或者 end 指返回指定范围内 str 出现的次数
string.decode(encoding='UTF-8', errors='strict')
以 encoding 指定的编码格式解码 string,如果出错默认报ValueError 的异常,除非 errors 指定的是'ignore'或'replace'
string.encode(encoding='UTF-8', errors='strict')
以 encoding 指定的编码格式编码 string,如果出错默认报ValueError的异常, 除非errors指定的是'ignore'或者'repl
string.endswith(obj, beg=0, end=len(string))
检查字符串是否以 obj 结束,如果 beg 或者 end 指定则检定的范围内是否以 obj 结束, 如果是, 返回True,否则返回Fa
string.expandtabs(tabsize=8)
把字符串 string 中的 tab 符号转为空格, 默认格数 tabsize 是 8.
string.find(str, beg=0, end=len(string))
检测 str 是否包含在 string 中,如果 beg 和 end 指定范则检查是否包含在指定范围内,如果是返回开始的索引值,返回-1
string.index(str, beg=0, end=len(string))
跟find()方法一样, 只不过如果str不在string中会报一个异
string.isalnum()
a, b, c R如果string至少有一个字符并且所有字符都是字母或数字回 True,否则返回 False
string.isalpha()
a, b, c 如果string至少有一个字符并且所有字符都是字母则返回T否则返回 False
string.isdecimal()
b, c, d 如果 string 只包含十进制数字则返回 True 否则返回 False.
string.isdigit()
b, c 如果 string 只包含数字则返回 True 否则返回 False.
string.islower()
b, c 如果 string 中包含至少一个区分大小写的字符,并且所有这些(大小写的)字符都是小写,则返回 True,否则返回 False
string.isnumeric()
b, c, d 如果 string 中只包含数字字符,则返回 True,否则返回 False
string.isspace()
b, c 如果 string 中只包含空格,则返回 True,否则返回 False.
string.istitle()
b, c 如果 string 是标题化的(见 title())则返回 True,否则返回 False
string.isupper()
b, c 如果 string 中包含至少一个区分大小写的字符, 并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
string.join(seq)
Merges (concatenates)以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
string.ljust(width)
返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
string.lower()
转换 string 中所有大写字符为小写.
string.lstrip()
截掉 string 左边的空格
string.partition(str)
e 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把 字 符 串 string 分 成 一 个 3 元 素 的 元 组 (string_pre_str,str,string_post_str),如果 string 中不包含str 则 string_pre_str == string.
string.replace(str1, str2, num=string.count(str1))
把 string 中的 str1 替换成 str2,如果 num 指定, 则替换不超过 num 次.
string.rfind(str, beg=0,end=len(string))
类似于 find()函数,不过是从右边开始查找.
string.rindex( str, beg=0,end=len(string))
类似于 index(), 不过是从右边开始.
string.rjust(width)
返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
string.rpartition(str)
e 类似于 partition()函数,不过是从右边开始查找.
string.rstrip()
删除 string 字符串末尾的空格.
string.split(str="", num=string.count(str))
以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串
string.splitlines(num=string.count('\n'))
b, c按照行分隔, 返回一个包含各行作为元素的列表, 如果 num 指定则仅切片 num 个行.
string.startswith(obj, beg=0,end=len(string))
b, e检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查.
string.strip([obj])
在 string 上执行 lstrip()和 rstrip()
string.swapcase()
翻转 string 中的大小写
string.title()
b, c 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
string.translate(str, del="")
根据str给出的表(包含256个字符)转换string的字符,要过滤掉的字符放到 del 参数中
string.upper()
转换 string 中的小写字母为大写
string.zfill(width)
返回长度为 width 的字符串,原字符串 string 右对齐,前面填充0
正则表达式
1、 为什么要学习正则:主要是为了处理字符串更加方便,特别是为后面进行代码生成做储备。
2、 match是匹配字符串的开头是否匹配,而search是查看字符串任意起始位置是否满足。
3、 sub可以对字符串中模式匹配的部分进行替换
4、 split:可以对字符串进行分割,这里是根据模式分割。
函数的使用:
1、 函数的作用域:函数中定义一个变量,如果和全局变量重名,则全局变量名称就会被覆盖,也就是,这里对这个变量的更改,不会更改全局变量。但是,如果直接使用的话,是会使用全局变量的。同时,如果想要修改全局变量,需要制定是全局变量:global a
2、 xrange用法和range一样,不过更为高效,因为他不会在内存中创建列表。所以,它只能用于循环。
3、 如果函数没有return语句,则他的返回值为None。
4、 关于函数的入参判断:如果如此为空,可能会发生异常。当异常发生后,可能会出现一种情况,一个事情做到了一半,就没有在进行下去,可能会造成内存泄露。这个问题如何解决?按照C的方式,每个入参都做判断是可以解决的,但是这样太麻烦了。而且看很多开源代码页没有这样来做。是不是有更好的方法?换一种思路,在调用之前确保不为空。在看看开源的代码是怎么做的。特别是openstack。
5、 可变入参:args, kwargs表示可变入参。
def funtest(a, b, c):
print(a, b, c)
def fun2(args, kwargs):
funtest(args, kwargs)
fun2(1,2,3)
也可以这样定义:
fun2(a, args, kwargs)
如何从可变参数中解析出参数的值?
在fun2中添加打印:可以发现,其实args是一个元组,kwargs是一个字典。
分析:调用fun2(1,2,3),会把a赋值给a,2赋值给元组args,{‘c’=3}赋值给kwargs.
args和kwargs的顺序不可颠倒。
args和kwargs可能同时都有值。这样,要获取指定的入参,首先根据看args中有没有,然后根据字符串看kwargs中是否存在。
如何建一个元组或者字典通过参数传递给一个函数?
def funtest(a, b, c):
print(a, b, c)
d = {'a':1, 'b':2,'c':3}
l = (1,2,3)
funtest(l)
funtest(d)
和在Python中可以实现这个功能。这样会很灵活的。
和也可以单独出现。但是,如果同时出现,必须在之前。
6、 默认参数或者可选参数,参数顺序:调用时,可以指定默认参数中填充那个。
def funtest(a, b=1, c=2):
print(a, b, c)
funtest(1, c=5, b=6)
其实,即便定义为:def funtest(a, b, c),也可以通过funtest(1, c=5, b=6)的形式调用。
7、 参数组:args, *kwargs就是参数组,通过元组和字典将产生携带进来。这个特性有助于更为动态的代码生成。
8、 可变长度参数:
9、 函数的参数中如果有一个是元组,可以这样:
def fun(a, (b, c)):
print(a, b, c)
fun(1, (1,2))
10、 关于回调,可以使用闭包,生成器,以及对象的call属性。都可以封装状态。
闭包的使用:
1、 将组成函数的语句和语句的执行环境打包在一起形成的对象,成为闭包。
2、 2.7之前的闭包不支持关键字nonlocal。3.0之后才支持。所以2.7前的闭包不可以使用nonlocal。
3、 这样他就不可以对执行环境中的变量进行更改。
字典的使用:
1、 字典的删除:直接使用del dict[k]可能会引发异常;首先判断k是否存在则效率有些低;使用异常使程序结构看起来不好。一个好的方法是pop(k, default v)。这个删除一个k项,并且返回。如果不存在返回默认的v。如果不加默认值,则会引发异常。
2、 直接使用字典下标获取字典的值可能会引发一场。使用get方法则不会,如果不存在会返回none。另外,还可以设置不存在的默认值。
3、 通过字典格式化字符串:print “value is %(key)s” % kvdict
4、 items方法返回一个列表,列表中的元素是一个元组,第一个是key,第二个是value。比较好用的方法。
5、 iteritems:返回的是一个迭代器。如果想要迭代这个字典,iteritems会比items更高效一点。
6、 iterkeys则返回的是key的迭代器。keys返回的是key的list。
7、 values返回值的列表,itervalues返回的是vlaue的迭代器
8、 popitem会随机弹出(同时删除)一个项,则对于想要处理所有的元素,并且删除所有的元素是有帮助的。但是,如果没用元素的话,会抛出异常。
9、 viewitems,viewkeys,viewvalues:这三个函数返回的是一个view对象。这个类似于视图。分别表示(key, value)pair的列表,key的列表,value的列表。一个优点是,如果字典发生变化,view会同步发生变化。在迭代过程中,字典不允许改变,否则会报异常。
10、 字典的键值比较规则:如果是内置类型(int,str,tuple),则是以他们的值作为键值;如果是自定义对象,则是以对象的地址作为键值。——这一点没有完全证实。——最新的发现:对象的比较,内置类型,是因为他们都重写了默认的object的eq等方法,所以可以比较内容。自定义对象,没有重写,所以,他们的比较可能会不一样。object默认的比较是什么?目前还不明确,后面再补充吧。可能就是地址(或者对象的唯一标识),而不是对象的内容。涉及到字典,它不是使用的单纯的比较,而是使用的hash,它返回的是一个hash值,字典就是根据这个hash只来散布对象的。
列表的使用:
1、 列表的删除:不可以在遍历的过程中删除链表,这样会得到不可预知的后果。可以使用列表的过滤,来获得新的列表。
2、 列表的过滤:
def filterFun(node):#这个函数做了两个事情哎。
node.cycleCount = node.cycleCount - 1
return node.cycleCount < 0
timeoutList = filter(filterFun, timerList)
对timerList中的每个节点执行函数filterFun,根据filterFun返回的结果,为真的项组成一个新的列表。
3、 map: kvlist = map(lambda x:x.strip(), kvlist)。同时,map可以接受多个列表,这个时候,函数也会接受多个参数,分别表示列表的每一个元素:
kvlist = map(lambda x,y:x+y, [1,2,3], [4,5,6])
如果函数为None,则相当于函数zip:
zip([1,2,3], [4,5,6])
[(1,4),(2,5),(3,6)]
4、 生成器表达式:l = [node for node in xrange(5) if node - 3 < 0]:这个的这个方法一定程度上可以替代过滤器和map。
生成器表达式定义:
[expr for iter_var in iterable if cond_expr]
l = [2 for x in xrange(5)]#结果是生成一个含有5个2的列表
5、 print(reduce(lambda x,y: xy, [2 for x in xrange(38)]))
上面的这个语句是计算2的38次方的值。它用到的是二元函数reduce。它第一次调用是将第一个和第二个元素做入参,后面用他们的结果做x,新的元素做y,最后返回值。
另外,在获取一个38个2的列表也可以使用:[2] 38。这可能更可读一点。
6、 enumerate:对列表处理,返回的是列表的索引以及节点。
for index, node in enumerate(timerList):
if timerId == node.timerId and timerEvent == node.timerEvent:
del timerList[index]
7、 列表的分片:[1,2,3,4],l[1:-1]表示从索引从1到倒数第一个,不包含倒数第一个。如果要从某位置到最后,则应该:[1:]
8、 l[i:j:k]:表示切片,从i到j,步长为k。
9、 l[i:j]:表示从i到j,不包括索引j。
排序
1、 list自己提供了排序的函数:sort。
2、 sort的参数:
a) cmp是一个比较函数,输入两个元素,比较大小,返回值为-1,0,1.
b) key也是一个函数,入参为一个元素,返回这个元素的关键字。
c) reverse是一个标志位,表示升序还是降序。默认False是升序,True表示降序。
3、使用key和reverse的性能,优于cmp函数。时间是cmp函数的一半。
迭代的使用:
1、 迭代比直接使用列表遍历效率根据高。比如字典的keys函数返回的列表,以及iterkeys返回的迭代器。
2、 reversed() 内建函数将返回一个反序访问的迭代器.参数必须为序列。
3、 enumerate:返回一个迭代器:有索引值。
4、 for eachLine in myFile 替 换 for eachLine in myFile.readlines() :
5、 注意:在迭代的过程中不可以更改序列,否则会引发问题,导致迭代出错。
6、 可以自己定义一个类,可以迭代使用。不过需要定义方法:iter,next。
7、 filter(function, iterable):可以对迭代使用过滤器。
生成器的使用:
1、 yield关键字可以阻塞住函数的执行,并且保存当前的执行环境,整个包被称为生成器。
2、 生成器可以通过调用生成器函数来创建。生成器函数是指包含关键字yield的函数。
3、 生成器可以通过.next()来执行。每调用一次,就执行代码,直到遇到yield关键字停止,并且返回yield关键字后面的表达式的值。
4、 可以通过调用send()函数来发送消息到生成器中。a = yield l:表示将send的入参赋值给a。
5、 throw:允许客户端传入要抛出的任何异常。
6、 和throw相同,只不过是要抛出一个特定的异常:GeneratorExit。
7、 send只接受一个参数,但是可以通过传递元组的方式传递多个参数。
8、 类的方法也可以返回生成器,因为他本质上就是一个函数。
9、 在生成器使用的时候,如何获取它自身的send和nex函数?通过send二次传入是有些风险的,非常可能造成交叉引用,无法垃圾回收造成内存泄露。
10、 第一次,必须调用next来启动生成器。
装饰器的使用:
1、 装饰器本质上来说就是函数(或者是可调用对象),他们接受函数对象。装饰器仅仅用来装饰或者修饰函数的包装,返回一个修改后的函数对象,并将其赋值原来的标示符,并永久失去对原有函数的访问。
2、 什么是带参数的装饰器?其实就是一个函数,这个函数可以返回一个装饰器,同时这个函数可以接受参数。
3、 不带参数的装饰器要返回一个函数,这个函数就是用来替换原有的标示符的。
def decofun(fun):
def mydeco(args, *kwargs):
print('before fun!')
ret = fun(args, *kwargs)
print('after fun', ret)
return ret
return mydeco#新的函数,用于替换原有标示符
@decofun
def funtest():#funtest被替换为decofun
print('now in funtest!')
return 1
funtest()
4、 装饰器是可以重叠的,那么他们的顺序怎么样:
a) @decofun2
b) @decofun
c) def funtest():
d) print('now in funtest!')
e) return 1
f) 原理是,funtest首先被decofun包装,然后再被decofun2包装。也就是,调用的时候,首先调用的是最上面的装饰器(也就是decofun2)的函数前面部分,然后再调用decofun的函数前面部分,之后再调用funtest。funtest返回后,首先调用的是decofun的函数后面部分,再调用decofun2后面部分。类似于一个栈的结构。
5、 装饰器不要滥用。如果一个装饰器只用了一次,要考虑他存在的必要了。
6、 携带参数的装饰器:
7、 def decoarg(arg):
a) def decofun3(fun):
b) def _mydeco(args, *kwargs):
c) print('decoarg before fun!', arg)
d) ret = fun(args, *kwargs)
e) print('decoarg after fun', ret)
f) return ret
g) return _mydeco
h) return decofun3
8、 装饰器用到的一个最重要的技术,就是闭包。装饰器函数返回的其实就是一个闭包。
9、 装饰器也可以修饰类的方法:
class testc:
def init(self):
self.i = 1
@decoarg(1)
@decofun2
@decofun
def call(self):
print('i is %d' % self.i)
注意:装饰器修饰类方法是无法被子类继承的(或者说子类的方法是没有被修饰的)。因为他本质上就是一个函数。
10、 装饰器也可以使对象,比如:
a) class obj:
b) def init(self, fun):
c) self.fun = fun
d)
e) def call(self, args, *kwargs):
f) print('decofun before fun!', args, kwargs)
g) ret = self.fun(args, *kwargs)
h) print('decofun after fun', ret)
i) return ret
j) @objdeco
k) def funtest(a, b=2):
l) print('funtest1 a , b =', a, b)
a) 这种方法看起来复杂了,但是可能会在有时候会比较有用。
11、 装饰器可以修饰类。这个时候装饰器接收的是一个类名,而返回的也是这个类名。它可以为这个类添加一些属性或者进行一些操作。
各位同学注意啦!!
想获取更多视频或者有任何学习问题
欢迎加入我的Python交流群
626062078