1 python是大小写敏感的python
2 遍历一个字典的键值:linux
for a in dict_obj.keys(): print a
3 列表解析功能可让代码很简洁,好比:
squared = [x ** 2 for i in range(0, 3)]
还能够加上筛选条件:
squared = [x ** 2 for i in range(0, 3) if not x % 2]算法
4 python的一些命名风格:
__xxx__:系统定义的名字
__xxx:类中的私有变量名sql
5 在python程序中,咱们常常看到
if __name__ == '__main__'这样的语句,这条语句通常写为顶级执行代码,__name__是一个系统变量,当程序是被其它模块导入时,该值为模块名字,当直接执行该文件时该值为'__main__'express
6 del语句可以直接释放资源编程
7 python的垃圾收集器其实是一个引用计数器和一个循环垃圾收集器,循环垃圾收集器是指会尝试清理未引用的循环windows
8 使用局部变量替换模块变量,能够加快查找速度,由于省去了名字查询,举例:
ls = os.linesep
os.linesep返回的是当前系统的行终止符,好比linux系统的是'\n',windows系统的是'\r\n',Mac系统的是'\r'
若是每次都使用os.linesep则解释器须要先确认os是一个模块,而后从该模块中找linesep变量,取一个本地变量名,查找速度会快不少,因此若是频繁使用时可使用本地变量来替换模块变量数组
9 Python提供了is和is not运算符来测试两个变量是否指向同一个对象
a is b 等价于 id(a) == id(b)服务器
10 [::1]这是一种扩展切片操做,其第三个参数你能够当作是range函数的那个步长参数,好比
str = 'abcdefg'
则str[::2]就等于aceg
str[::-1]就等于gfedcba网络
11 在python中单引号和双引号括起来的字符串是没有区别的,不像其它脚本语言,在双引号还有些转义的东西,由于python对字符串的处理是当作一个标量,建立了后是不改变的,修改则是建立了一个新的字符串标量对象
12 for-else语句是指若是for循环中所有循环完了没有break则会执行else语句
因此这里有个巨坑:
for j in range(i+step, num_len, step): pass
觉得当j不知足num_len时退出,觉得j>=num_len,结果是若是j+step>=num_len就退出,j并无加上step
解决方法能够:
for j in range(i+step, num_len, step): pass else: j += step
13 格式化字符串有两种,一种是元组做为参数类型的,相似于C模式的格式化输出,另一种是字典做为参数的,分别示例以下:
'yy:%s %s' %('oo', 'ii')
'yy%(abc)s' %{'oo':77, 'abc':99}
字符串模板:它至关于定义了一个模板,传参套用便可,substitute还有个类似的成员函数:safe_substitute,区别是后者若是遇到key不存在时不是抛错,而是将模板字符串原封不动输出
from string import Template
s = Template('abc ${haha} abc')
print s.substitute(haha='99')
14 原始字符串操做符:r/R
用法是在字符串引号前加上小写r或大写R:好比r'\n'
也就是说它消除了转义符等,表达了真实要表达的字符
print '\n'会输出换行的空行
print r'\n'则是输出\n
r'\n'至关于字符串'\\n'
15 python的三引号能够用来包含多行字符的字符串,字符串中能够包含换行符、制表符等
16 列表可使用大部分的对象和序列类型的操做符,此外,列表也有属于本身的方法,好比列表解析,在逻辑上描述要建立的列表的内容,举例:
>>> [i * 2 for i in [8, -2, 5]]
[16, -4, 10]
17 字符串排序使用的是字典序,而不是字母序,即比较ASCII码值,好比:
>>> s = ['aaa', 'TTT']
>>> print sorted(s)
['TTT', 'aaa']
由于'T'的ASCII码值比'a'的小
18 python中也是有数组模块的,array模块,不过通常可用list替代
19 检查一个字典中包含某个键能够用has_key方法或者用in和not in来检查,has_key方法在后面可能会被弃用
if uuu.has_key('ddd'): xxx if 'ddd' in uuu: xxx
20 字典的键必须是可哈希的,可使用hash函数来判断键是不是可哈希的,若是是则返回哈希后的值,不然抛出异常
21 字典的keys()、values()和items()方法都是返回列表,iterkeys()、itervalues()和itemvalues()返回的是一个迭代器,因此当字典量大,要遍历时iter的这些方法优点就是节省内存。
for i in kk.keys(): print i for i in kk.iterkeys(): print i
结果是同样的
print kk.keys() print kk.iterkeys()
这二者则不一样了,可本身打出来看下
22 python中有一个叫集合的数据结构,集合的元素必须是可哈希的,可以使用set工厂方法来建立,建立不变的集合使用frozenset工厂方法
>>>s = set('ghj') >>>s set(['g', 'h', 'j'])
集合的特别是处就在于它跟数学中的集合概念很类似,同时提供了一些操做符很方便的操做集合,好比大于小于号用来判断子集关系,-用于补集,&用于交集,|用于并集,+号不是集合类型的运算符
23 相似C语言中的三元操做符:samller = x if x < y else y
24 python的zip函数,以可迭代对象做为参数,将对象中对应的元素打包成一个个元组,而后返回由这些元组组成的列表。例:
>>>a = [1, 2, 3] >>>b = [4, 5, 6, 7] >>>zipped = zip(a, b) [(1, 4), (2, 5), (3, 6)]
利用*号操做符可将元组加压为列表
>>>zip(*zipped)
[(1, 2, 3), (4, 5, 6)]
25 迭代器从根本上来讲是一个next()方法的对象,条目所有获取完成后会引起一个StopInteration异常来告诉外部调用者迭代完成了。
它的做用:
(1)带来访问性能上的提高
(2)可建立更简洁可读的代码
建立迭代器的方法:
iter(obj)可返回一个对象的迭代器,调用了该对象的__iter__方法和next方法
iter(func, sentinel);若是是传递了两个参数给iter函数,则它会重复的调用func,直到迭代器的下个值等于sentinel。
文件也是可迭代的python数据类型,文件对象生成的迭代器会自动调用readline方法,因此有:
for eachLine in myFile:
26 列表解析
解析语法:
[expr for iter_var in iterable]
eg:[x ** 2 for x in range(6)]
扩展版本的语法:
[expr for iter_var in iterable if cond_expr]
eg:[x for x in seq if x % 2]
列表解析支持多重嵌套for 循环以及多个 if 子句
eg:[(x+1,y+1) for x in range(3) for y in range(5)]
27 生成器表达式
生成器是特定的函数,容许你返回一个值,而后“暂停”代码的执行,稍后恢复。
为啥须要生成器表达式:列表解析的一个不足就是必要生成全部的数据, 用以建立整个列表. 这可能对有大量数据的迭
代器有负面效应. 生成器表达式经过结合列表解析和生成器解决了这个问题,是一个内存使用更友好的结构。
生成器表达式:(expr for iter_var in iterable if cond_expr)
举例:sum(len(word) for line in data for word in line.split())
28 能够从sys.argv对象中获取程序参数,相似于C语言中的argv参数,sys.argv[0]永远是程序的名称。
29 可以使用pickle模块将对象进行序列化,包括用户本身定义的类,cPickle是pickle的一个更快的C语言编译版本。shelve则不只提供了序列化功能还提供了对象的永久性存储功能。
30 异常处理
try xxx except Exception1, e: pass except Exception2, e: pass
若是两个异常类型使用同一种方法处理,则能够把异常类型一同放在元组里
try: xxx except (Exception1, Exception2), e: pass
BaseException是全部异常类的基类,KeyboardInterrupt和systemExit被从Exception中移出来,和Exception处于同级,其它的内建异常类都是以Exception为基类
try-except-else-finally
31 能够对一个实例进行__class__函数调用,能够显示出该实例属于哪一个类
32 with
with context_expr [as var]:
with_suite
with语句仅能工做于支持上下文管理协议的对象,只有内建了"上下文管理"的对象能够和 with 一块儿工做。
下面列出一些支持该协议对象的第一批成员简短列表:
file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore
以打开文件举例:
with open('/etc/passwd', 'r') as f: for eachLine in f: # ...do stuff with eachLine or f...
这里是with语句帮你打开文件和结束时自动关闭文件,实现原理:
上下文表达式(context_expr),上下文管理器
当with语句执行时便开始执行上下文符号(with和as之间的内容)来得到一个上下文管理器,上下文管理器用来提供一个上下文对象。这是经过调用__context__()方法来实现的,该方法返回一个上下文对象。获取上下文对象后会执行__enter__()方法来作with包含的语句块执行前的准备工做,若是有as声明变量,则该变量会被赋值为__enter__()方法返回的值。
不管with语句块正常执行结束仍是异常结束,结束时都会先调用__exit__()方法,好比能够在该方法中关闭上下文对象,该方法会有三个参数,若是正常结束,则返回3个None,若是异常结束,等同于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和回溯(traceback)。__exit__方法返回值是true or false决定了会往下执行with后的代码仍是抛出异常给用户。
33 exc_info函数
是另外一种获取异常信息的途径,返回一个元组,包含3个对象,分别是:
(1)exc_type:异常类
(2)exc_value:异常类的实例
(3)exc_traceback:追踪(traceback)对象
eg:
try: float('jjf') except: import sys exc_tuple = sys.exc_info() for each_item in exc_tuple: print each_item
34 装饰器
首先介绍一个装饰器实用的地方,好比定义一个类的静态方法,若是没有使用装饰器,须要在该方法的第一行加上staticFoo = staticmethod(staticFoo),显得臃肿,若是使用装饰器则只须要在方法的上面加上@staticmethod便可。
@deco2 @deco1 def func(arg1, arg2, ...): pass
等价于:
def func(arg1, arg2, ...): pass func = deco2(deco1(func))
先调用deco2,而后在deco2里调用deco1,最后deco1里调用func
上面说的是无参数的装饰器,下面说下有参数的装饰器:
@decomaker(deco_args) def foo(): pass
须要本身返回以函数foo做为参数的装饰器。换句话说,decomaker()用 deco_args 作了些事并返回
函数对象(装饰器返回的函数,不是foo),而该函数对象正是以 foo 做为其参数的装饰器。简单的说来:
foo = decomaker(deco_args)(foo)
因此有参数和无参数的装饰器结合起来就是:
@deco1(deco_arg) @deco2 def func(): pass
等价于:
func = deco1(deco_arg)(deco2(func))
举例(不带参数的):
#!/usr/bin/env python from time import ctime, sleep def tsfunc(func): def wrappedFunc(): print '[%s] %s() called' % (ctime(), func.__name__) return func() return wrappedFunc @tsfunc def foo(): print 'ok' foo() sleep(4) for i in range(2): sleep(1) foo()
输出:
[Sun Mar 10 01:29:36 2019] foo() called
ok
[Sun Mar 10 01:29:41 2019] foo() called
ok
[Sun Mar 10 01:29:42 2019] foo() called
ok
疑问地方:
(1)
def tsfunc(func): #def wrappedFunc(): # print '[%s] %s() called' % (ctime(), func.__name__) # return func() #return wrappedFunc print '[%s] %s() called' % (ctime(), func.__name__) return func
为何须要闭包函数,为何这样子进行调用只打了一次时间戳?
举例(带参数的):
def outer(outer_args): def middle(func): def wrapper(*args,**kwargs): print("before func") print("use args: "+outer_args) wrapper_result=func(*args,**kwargs) print("after func") return wrapper_result return wrapper return middle @outer("hello") def foo(a,b): return a+b
35 函数的参数
能够传递元组或者字典,*tuple_param,**dict_param
这里能够区分下非关键字参数和关键字参数,像b='1'这样的就叫作关键字参数,因此字典便是关键字参数;非关键字参数须要放到关键字参数以前
test(*tuple, **dict_param)
python是容许传递默认参数的,好比你常常会看到一个函数的定义的参数末尾是这样的,uuu='abc',但要注意全部的必要参数要放在默认参数的后面,为何要这样规定呢,简单来讲就是若是容许这样随意混杂,有些状况会有歧义的。
好比不容许这样:def test(a, b='1', c)
应该这样:def test(a, c, b='1')
对于函数的参数定义一样很灵活,能够经过元组和字典定义可变参数的函数:def function_name([formal_args,][*vargst,] **vargsd)
其实就是对于非关键字参数formal_args中没有的则会放到vargst元组里,对于关键字参数就放到vargsd中
36 匿名函数与 lambda
lambda [arg1[, arg2, ... argN]]: expression
eg:
>>> hh = lambda x, y=3: x+y >>> hh(5) 8 >>> hh(5, 9) 14 >>> type(hh) <type 'function'>
37 函数式编程的内建函数,apply,filter,map和reduce:
apply(func[, nkw][, kw]) :用可选的参数来调用func函数,该函数其实已被抛弃,由于如今的函数已经支持可选参数调用了。
eg:
apply(test, *tuple_param)
filter(func, seq):调用一个返回布尔值的函数func来迭代sql中的每一个元素,若是是返回True的则插入到要返回的列表中
eg:
filter(test, [1, 4, 8])
好比test是对偶数进行删选的函数,则返回[4, 8]
map(func, seq1[,seq2...]):该函数跟filter函数有点像,不过func函数不必定是要布尔函数,它能够对序列里的每一个元素进行处理并返回值,该值再插入到列表中,最后返回列表。
reduce(func, seq[, init]):func是一个二元函数,做用于seq序列的元素,每次携带一对(先前的结果以及下一个序列元素),这样一直计算到最后一个。
eg:
reduce(lambda x, y:x+y, [1, 2, 3])
算法实现是先拿出第一个,而后陆续从第2个开始。
>>> reduce(lambda x, y:x-5, [1, 3, 5])
-9
>>> reduce(lambda x, y:x-5, [1])
1
下面这个例子就能够看出来,先拿出1获得1,而后拿出3,获得-4,而后拿出5获得-9
38 使用global关键字可引用全局变量
ii = 3 def test(): global ii ii = 7 print ii
39 生成器
生成器是一个带 yield 语句的函数。一个函数或者子程序只返回一次,但一个生成器能暂停执行并返回一个中间的结果----那就是 yield 语句的功能, 返回一个值给调用者并暂停执行。当生成器的 next()方法被调用的时候,它会准确地从离开地方继续。
简单的生成器例子:
#!/usr/bin/env python def simpleGen(): yield 1 yield '2' gs = simpleGen() print gs.next() print gs.next() #print gs.next() # StopIteration for item in simpleGen(): print item
除了next方法,增强的生成器还有send和close方法,send方法用于向生成器传递值,好比下面例子的val,close方法用来关闭生成器,好比下面例子的最后一行就会报stopInteration异常
#!/usr/bin/env python def counter(start_at=0): count = start_at while True: val = (yield count) if val is not None: count = val else: count += 1 kk = counter(10) print kk.next() print kk.next() print kk.send(1) print kk.next() kk.close() print kk.next()
输出:
10
11
1
2
Traceback (most recent call last):
File "test_python.py", line 16, in <module>
print kk.next()
StopIteration
40 模块和命名空间相关
一个文件被看做是一个独立模块, 一个模块也能够被看做是一个文件。 模块的文件名就是模块的名字加上扩展名 .py。
sys.path能够看到当前的搜索路径,import的时候就是去这些路径下找文件模块的
若是想添加新得搜索路径,能够调用sys.path.append('xxx'),好比sys.path.append('/root/oo/')
sys.modules则能够看到当前导入的模块名称和对应的物理位置,是字典对象,key为模块名,value为物理位置,好比'kk': <module 'kk' from '/root/oo/kk.py'>
名称空间是名称(标识符)到对象的映射
在程序执行时会有3个名称空间:这三个名称空间分别是局部名称空间, 全局名称空间和内建名称空间
Python 解释器首先加载内建名称空间。 它由 __builtins__ 模块中的名字构成。 随后加载执行模块的全局名称空间, 它会在模块开始执行后变为活动名称空间,在函数调用时就会出现有局部名称空间。
经过 globals() 和 locals() 内建函数判断出某一名字属于哪一个名称空间。
globals() 和 locals() 内建函数分别返回调用者全局和局部名称空间的字典。
举例:
#!/usr/bin/env python o = 8 def yy(): i = 9 print locals() print globals() print locals().keys() yy()
输出:
{'i': 9}
{'__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test_python.py', 'o': 8, '__package__': None, 'yy': <function yy at 0x7fedd7c6e578>, '__name__': '__main__', '__doc__': None}
['i']
因此能够判断一个变量在当前名称空间是否存在,能够这样判断if 'xxx' in locals().keys()
当你获得一个函数实例或一个类实例时,至关于你建立了一个名称空间,你能够将想要的东西放入这个名称空间里,好比:
#!/usr/bin/env python def foo(): pass foo.__doc__ = 'Oops, forgot to add doc str above!' foo.version = 0.2 print foo.version class abc(): pass a = abc() a.uu = 9 print a.uu
模块导入的方式有好几种:
import xxx
from xx import xxx
from xx import xxx as x
加载模块会让该模块的顶层代码被执行。
41.包
包是一个有层次的文件目录结构, 它定义了一个由模块和子包组成的Python应用程序执行环境
每一个包的目录都会有__init__.py文件,能够是空文件,有时在from-import导入子包时会用到它
导入有绝对导入和相对导入两种方式,绝对导入是默认的比较经常使用的方式,import只支持绝对导入,from-import支持相对导入
相对导入:语法的第一部分是一个句点, 指示一个相对的导入操做。 以后的其余附加句点表明当前from起始查找位置后的一个级别,能够相对导入看起来没有那么清晰
只要在你的 Python 模块头部加入一个额外的编码指示说明就可让导入者使用指定的编码解析你的模块, 编码对应的 Unicode 字符串
好比utf-8编码:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
有时咱们会遇到包的循环导入问题,好比A文件中import B,B中又也是import A,解决方法能够是若是某方只是想要某个函数用一些另一个模块的,能够在那个函数里内部导入下,由于此时运行时就不会有互相导入致使循环问题,或者引入第三方,把要调用的集成到另一个公共模块
42.类
初始化一个类实例时会调用类的__init__方法,你能够把它理解为类的构造方法
python的OOP面相对象编程中的经常使用术语:
(1)抽象/实现:抽象就是对现实问题的一种抽象建模,以程序的方式来描述现实;实现则是根据建好的模赋予真实数据并交互起来
(2)封装/接口:封装便是把具体实现隐藏起来,只须要提供相对应的调用接口便可,告诉用户只要这样调用接口就能实现相对应的功能
(3)合成:一个类里面可能引用了其它类,几个类联合起来解决实际的问题
(4)派生/继承:派生就是继承了一个父类后子类本身定义的方法实现,父类没有的,继承便是继承了父类的一些属性和方法
(5)泛化/特化:泛化是指子类、父类及其祖先都有的一个特定属性功能,好比各类人本质都是一我的,有追根溯源的味道,特化是指子类有其本身特定的某些功能,即虽然都是人,可是我有其它人不会的技能
(6)多态:多态的概念指出了对象如何经过他们共同的属性和动做来操做及访问,而不需考虑他们具体的类。最简单的实用例子就是咱们能够根据不一样的配置选择不一样的driver类实现,而后调用对应类的方法,由于这些类都有这些方法,但实际调用哪一个类,则要看driver是实例化了哪一个子类。
(7)反射:这个性质展现了某对象是如何在运行期取得自身信息的。若是传一个对象给你,你能够查出它有什么能力,dir()和 type()内建函数便是用到了这种能力。
类的数据属性:数据属性仅仅是所定义的类的变量,咱们成为静态变量,相似于C++中的在一个变量定义前加了个static
#!/usr/bin/env python class A(object): jk = 1 def update(self, value): self.jk = value # 并无影响到类的属性jk,只是建立了个实例属性 print A.jk a = A() a.update(3) print A.jk print a.jk
输出:
1
1
3
在类属性可变的状况下,好比类属性是dict结构的,类实例能够改变掉类对象的属性值:
class A(object): jk = 1 kk = {'a': 1} a = A() a.jk = 2 a.kk['a'] = 2 print A.jk print A.kk
输出:
1
{'a': 2}
要知道类的属性能够有几种方法:
(1)经过调用内建函数dir()
(2)访问类的__dict__属性
(3)内建的vars()函数接受类对象做为参数,返回类的__dict__属性的内容
特殊类属性
A.__name__ 类A的名字(字符串)
A.__doc__ 类A的文档字符串
A.__bases__ 类A的全部父类构成的元组
A.__dict__ 类A的属性
A.__module__ 类A定义所在的模块(1.5 版本新增)
A.__class__ 实例A对应的类(仅新式类中)
显示调用父类方法:
class A(object): jk = 1 def __init__(self): print 'A class' class B(A): def __init__(self): print('B class') super(B, self).__init__() # 或者是:A.__init__(self) kb = B()
与__init__()相比,__new__()方法更像一个真正的构造器。__new__()必须返回一个合法的实例,这样解释器在调用__init__()时,就能够把这个实例做为 self 传给它
__del__() "解构器"方法
除非你知道你正在干什么,不然不要去实现__del__()
若是你定义了__del__,而且实例是某个循环的一部分,垃圾回收器将不会终止这个循环——你须要自已显式调用 del
类里面有staticmethod()和 classmethod()内建函数,能够将方法变为静态方法和类方法,如今通常用装饰器来实现静态方法和类方法的转换,静态方法咱们比较熟悉,比较不熟悉的是类方法,类方法区别去静态方法的是它须要传递一个类对象参数,它的比较大的用处在于让咱们尝试一种另类的构造函数。可看下面例子:
class Date(object): @classmethod def from_string(cls, date_as_string): day, month, year = map(date_as_string.split('-')) date1 = cls(day, month, year) return date1 date2 = Date.from_string('11-09-2012')
cls表示类对象,而不是类实例
至关于咱们调用了类方法from_string来构造一个类实例并返回
其实重写覆盖__new__方法也同样实现这个功能
class RoundFloat(float): def __new__(cls, val): return float.__new__(cls, round(val, 2)) #或者return super(RoundFloat, cls).__new__(cls, round(val, 2))
注意python的类的方法是不支持重载特性的,但可覆盖方法,也就是说不能像C++那样,参数多少均可以被重载为两个不一样的方法
isinstance函数能够用来判断一个对象是否属于某个给定的类的实例:
i = 8 if isinstance(i, int): print 'yes' else: print 'no'
类属性的一些经常使用方法:
hasattr():返回值示Boolean型的,查询是否有该属性;
getattr():获取某个属性的值,若是没有会引起AttributeError异常,除非有给默认参数;
setattr():设置属性
delattr():删除属性
重写一些方法能够定制类的特殊方法,这些特殊方法都是__开头的:
__cmp__(self, obj) 对象比较;内建 cmp()
还有不少大于小于加减乘除等
43 网络编程相关
套接字有两种,分别是基于文件型的和基于网络型的,分别是AF_UNIX(AF_LOCAL)和AF_INET
python还支持一种套接字AF_NETLINK,AF_NETLINK套接字家族让用户代码与内核代码之间的IPC可使用标准BSD套接字接口。
不管是哪一种类型的套接字,都分为两种类型套接字,面向链接和无链接套接字。
面向链接套接字通信前要先创建一条链接,这种通信方式提供了顺序的、可靠的、不会重复的数据传输,并且也不会被加上数据边界。实现这种链接的主要协议就是传输控制协议(TCP),套接字类型对应为SOCK_STREAM。这些套接字使用Internet协议(IP协议)来查找主机,因此联合起来是TCP/IP。
无链接套接字与面向链接相反,发送数据前不用先创建链接,但这也意味着数据不必定保证送到,且发送数据顺序和数据包重复没法获得保证,但这样的好处是性能好,在某些场景下有用。
实现这种链接的主要协议是数据报协议(UDP),套接字类型为SOCK_DGRAM,UDP/IP。
使用socket.socket()函数来建立套接字
socket(socket_family, socket_type, protocol=0)
socket_family 能够是 AF_UNIX 或 AF_INET。socket_type 能够是 SOCK_STREAM 或 SOCK_DGRAM。protocol 通常不填,默认值为 0。
套接字对象的经常使用函数:
服务器端套接字函数
s.bind() 绑定地址(主机,端口号对)到套接字
s.listen() 开始 TCP 监听
s.accept() 被动接受 TCP 客户的链接,(阻塞式)等待链接的到来
客户端套接字函数
s.connect() 主动初始化 TCP 服务器链接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛异常
公共用途的套接字函数
s.recv() 接收 TCP 数据
s.send() 发送 TCP 数据
s.sendall() 完整发送 TCP 数据
s.recvfrom() 接收 UDP 数据
s.sendto() 发送 UDP 数据
s.getpeername() 链接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
Blocking-Oriented Socket Methods
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操做的超时时间
s.gettimeout() 获得阻塞套接字操做的超时时间
面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 建立一个与该套接字关连的文件
一个简单的socket服务器例子:
#!/usr/bin/env python from socket import * from time import ctime HOST = '' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpSerSock = socket(AF_INET, SOCK_STREAM) tcpSerSock.bind(ADDR) tcpSerSock.listen(5) while True: print 'waiting for connection...' tcpCliSock, addr = tcpSerSock.accept() print '...connected from:', addr try: while True: data = tcpCliSock.recv(BUFSIZ) if not data: break tcpCliSock.send('[%s] %s' % (ctime(), data)) except Exception, e: print e tcpCliSock.close() tcpSerSock.close()
一个简单的客户端例子:
#!/usr/bin/env python from socket import * HOST = 'localhost' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) while True: data = raw_input('> ') if not data: break tcpCliSock.send(data) data = tcpCliSock.recv(BUFSIZ) if not data: break print data tcpCliSock.close()
SocketServer模块:
#!/usr/bin/env python from SocketServer import (TCPServer as TCP, StreamRequestHandler as SRH) from time import ctime HOST = '' PORT = 21567 ADDR = (HOST, PORT) class MyRequestHandler(SRH): def handle(self): print '...connected from:', self.client_address self.wfile.write('[%s] %s' % (ctime(), self.rfile.readline())) # self.request.send('[%s] %s' % (ctime(), self.request.recv(1024))) tcpServ = TCP(ADDR, MyRequestHandler) print 'waiting for connection...' tcpServ.serve_forever()