模块三—面向对象
2018-06-18 00:43:27来源:未知 阅读 ()
1.subprocess
随着python版本的更新,过多的模块引起代码的复杂与冗余,因此Python新引入了一个模块subprocess,将以上几个模块中的功能集中到它当中,以后我们只需import这一个即可。用于尝试取代os.system 、os.spawn*、os.popen*、popen2.*、commands.*
os.system 输出命令结果到屏幕
>>> os.system("dir") 驱动器 C 中的卷是 System 卷的序列号是 E445-0B46 C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32 的目录 2017/04/26 16:23 <DIR> . 2017/04/26 16:23 <DIR> .. 2017/04/26 16:23 <DIR> DLLs 2017/04/26 16:23 <DIR> Doc 2017/04/26 16:23 <DIR> include 2017/04/26 16:23 <DIR> Lib 2017/04/26 16:23 <DIR> libs 2017/03/21 18:01 30,351 LICENSE.txt 2017/03/21 17:48 334,939 NEWS.txt 2017/03/21 17:58 97,944 python.exe 2017/03/21 17:55 58,008 python3.dll 2017/03/21 17:55 3,263,640 python36.dll 2017/03/21 17:58 96,408 pythonw.exe 2017/04/26 16:23 <DIR> Scripts 2017/04/26 16:23 <DIR> tcl 2017/04/26 16:23 <DIR> Tools 2016/06/09 22:46 83,784 vcruntime140.dll 7 个文件 3,965,074 字节 10 个目录 58,043,895,808 可用字节 0 >>> res=os.system("dir") 驱动器 C 中的卷是 System 卷的序列号是 E445-0B46 C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32 的目录 2017/04/26 16:23 <DIR> . 2017/04/26 16:23 <DIR> .. 2017/04/26 16:23 <DIR> DLLs 2017/04/26 16:23 <DIR> Doc 2017/04/26 16:23 <DIR> include 2017/04/26 16:23 <DIR> Lib 2017/04/26 16:23 <DIR> libs 2017/03/21 18:01 30,351 LICENSE.txt 2017/03/21 17:48 334,939 NEWS.txt 2017/03/21 17:58 97,944 python.exe 2017/03/21 17:55 58,008 python3.dll 2017/03/21 17:55 3,263,640 python36.dll 2017/03/21 17:58 96,408 pythonw.exe 2017/04/26 16:23 <DIR> Scripts 2017/04/26 16:23 <DIR> tcl 2017/04/26 16:23 <DIR> Tools 2016/06/09 22:46 83,784 vcruntime140.dll 7 个文件 3,965,074 字节 10 个目录 58,041,049,088 可用字节 >>> res 0 >>> res=os.system("dirdsf") 'dirdsf' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 >>> res 1
os.popen("dir").read() 会保存命令的执行结果输出
>>> os.system("dir") 驱动器 C 中的卷是 System 卷的序列号是 E445-0B46 C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32 的目录 2017/04/26 16:23 <DIR> . 2017/04/26 16:23 <DIR> .. 2017/04/26 16:23 <DIR> DLLs 2017/04/26 16:23 <DIR> Doc 2017/04/26 16:23 <DIR> include 2017/04/26 16:23 <DIR> Lib 2017/04/26 16:23 <DIR> libs 2017/03/21 18:01 30,351 LICENSE.txt 2017/03/21 17:48 334,939 NEWS.txt 2017/03/21 17:58 97,944 python.exe 2017/03/21 17:55 58,008 python3.dll 2017/03/21 17:55 3,263,640 python36.dll 2017/03/21 17:58 96,408 pythonw.exe 2017/04/26 16:23 <DIR> Scripts 2017/04/26 16:23 <DIR> tcl 2017/04/26 16:23 <DIR> Tools 2016/06/09 22:46 83,784 vcruntime140.dll 7 个文件 3,965,074 字节 10 个目录 58,043,895,808 可用字节 0 >>> res=os.system("dir") 驱动器 C 中的卷是 System 卷的序列号是 E445-0B46 C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32 的目录 2017/04/26 16:23 <DIR> . 2017/04/26 16:23 <DIR> .. 2017/04/26 16:23 <DIR> DLLs 2017/04/26 16:23 <DIR> Doc 2017/04/26 16:23 <DIR> include 2017/04/26 16:23 <DIR> Lib 2017/04/26 16:23 <DIR> libs 2017/03/21 18:01 30,351 LICENSE.txt 2017/03/21 17:48 334,939 NEWS.txt 2017/03/21 17:58 97,944 python.exe 2017/03/21 17:55 58,008 python3.dll 2017/03/21 17:55 3,263,640 python36.dll 2017/03/21 17:58 96,408 pythonw.exe 2017/04/26 16:23 <DIR> Scripts 2017/04/26 16:23 <DIR> tcl 2017/04/26 16:23 <DIR> Tools 2016/06/09 22:46 83,784 vcruntime140.dll 7 个文件 3,965,074 字节 10 个目录 58,041,049,088 可用字节 >>> res 0 >>> res=os.system("dirdsf") 'dirdsf' 不是内部或外部命令,也不是可运行的程序 或批处理文件。 >>> res 1
常用subprocess方法示例(subprocess的目的就是启动一个新的进程并且与之通信)
#call 执行命令,返回命令执行状态,0或非0
>>> import subprocess >>> retcode =subprocess.call(["ls","-l"]) total 8 drwxr-xr-x 6 tt tt 4096 Apr 18 2017 bank_proxy_mngt drwxr-xr-x 7 tt root 4096 Dec 19 14:43 PayRelaySvr >>> retcode 0
>>> retcode =subprocess.call(["ls","-M"]) ls: invalid option -- 'M' Try `ls --help' for more information. >>> retcode 2
#check_call 执行命令,如果命令结果为0,就正常返回,否则抛异常;
>>> subprocess.check_call("ls -l",shell=True) total 8 drwxr-xr-x 6 tt tt 4096 Apr 18 2017 bank_proxy_mngt drwxr-xr-x 7 tt root 4096 Dec 19 14:43 PayRelaySvr 0 >>> subprocess.check_call("ls -M",shell=True) ls: invalid option -- 'M' Try `ls --help' for more information. Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.6/subprocess.py", line 502, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command 'ls -M' returned non-zero exit status 2
#getstatusoutput 接收字符串格式命令,返回元祖形式,第一个元素是执行状态,第二个是命令结果;
import subprocess a=subprocess.getstatusoutput("dir") print(a) >>>(0, ' 驱动器 C 中的卷是 System\n 卷的序列号是 E445-0B46\n\n C:\\Users\\Administrator\\PycharmProjects\\untitled\\day6 的目录\n\n2017/12/19 19:36 <DIR> .\n2017/12/19 19:36 <DIR> ..\n2017/12/19 19:36 242 subprocess模块.py\n2017/12/19 19:20 <DIR> __pycache__\n 1 个文件 242 字节\n 3 个目录 57,140,039,680 可用字节') a=subprocess.getstatusoutput("ls /bin/ls") print(a) >>>(1, "'ls' 不是内部或外部命令,也不是可运行的程序\n或批处理文件。")
#getoutput 接收字符串格式命令,并返回结果
res=subprocess.getoutput("ls /bin/ls") print(res) >>>'ls' 不是内部或外部命令,也不是可运行的程序或批处理文件。
#check_output 执行命令,并返回结果,不是打印结果
res=subprocess.check_output("ipconfig",shell=True) print(res) >>>b'\r\nWindows IP \xc5\xe4\xd6\xc3\r\n\r\n\r\n\xd2\xd4\xcc\xab\xcd\xf8\xca\xca\xc5\xe4\xc6\xf7 \xb1\xbe\xb5\xd8\xc1\xac\xbd\xd3:\r\n\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n \xb1\xbe\xb5\xd8\xc1\xb4\xbd\xd3 IPv6 \xb5\xd8\xd6\xb7. . . . . . . . : fe80::19ca:8149:cc34:6a3%12\r\n IPv4 \xb5\xd8\xd6\xb7 . . . . . . . . . . . . : 10.75.102.28\r\n \xd7\xd3\xcd\xf8\xd1\xda\xc2\xeb . . . . . . . . . . . . : 255.255.255.0\r\n \xc4\xac\xc8\xcf\xcd\xf8\xb9\xd8. . . . . . . . . . . . . : 10.75.102.1\r\n\r\n\xd2\xd4\xcc\xab\xcd\xf8\xca\xca\xc5\xe4\xc6\xf7 VMware Network Adapter VMnet1:\r\n\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n \xb1\xbe\xb5\xd8\xc1\xb4\xbd\xd3 IPv6 \xb5\xd8\xd6\xb7. . . . . . . . : fe80::3590:8123:7f60:3159%16\r\n IPv4 \xb5\xd8\xd6\xb7 . . . . . . . . . . . . : 192.168.73.1\r\n \xd7\xd3\xcd\xf8\xd1\xda\xc2\xeb . . . . . . . . . . . . : 255.255.255.0\r\n \xc4\xac\xc8\xcf\xcd\xf8\xb9\xd8. . . . . . . . . . . . . : \r\n\r\n\xd2\xd4\xcc\xab\xcd\xf8\xca\xca\xc5\xe4\xc6\xf7 VMware Network Adapter VMnet8:\r\n\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n \xb1\xbe\xb5\xd8\xc1\xb4\xbd\xd3 IPv6 \xb5\xd8\xd6\xb7. . . . . . . . : fe80::3562:3759:2a87:ae7a%17\r\n IPv4 \xb5\xd8\xd6\xb7 . . . . . . . . . . . . : 192.168.220.1\r\n \xd7\xd3\xcd\xf8\xd1\xda\xc2\xeb . . . . . . . . . . . . : 255.255.255.0\r\n \xc4\xac\xc8\xcf\xcd\xf8\xb9\xd8. . . . . . . . . . . . . : \r\n\r\n\xcb\xed\xb5\xc0\xca\xca\xc5\xe4\xc6\xf7 isatap.{81DC3718-150D-426F-802F-53FB8632FD86}:\r\n\r\n \xc3\xbd\xcc\xe5\xd7\xb4\xcc\xac . . . . . . . . . . . . : \xc3\xbd\xcc\xe5\xd2\xd1\xb6\xcf\xbf\xaa\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n\r\n\xcb\xed\xb5\xc0\xca\xca\xc5\xe4\xc6\xf7 isatap.{5C35F50E-5717-4048-B734-96C2964824D5}:\r\n\r\n \xc3\xbd\xcc\xe5\xd7\xb4\xcc\xac . . . . . . . . . . . . : \xc3\xbd\xcc\xe5\xd2\xd1\xb6\xcf\xbf\xaa\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n\r\n\xcb\xed\xb5\xc0\xca\xca\xc5\xe4\xc6\xf7 \xb1\xbe\xb5\xd8\xc1\xac\xbd\xd3* 9:\r\n\r\n \xc3\xbd\xcc\xe5\xd7\xb4\xcc\xac . . . . . . . . . . . . : \xc3\xbd\xcc\xe5\xd2\xd1\xb6\xcf\xbf\xaa\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n\r\n\xcb\xed\xb5\xc0\xca\xca\xc5\xe4\xc6\xf7 isatap.{7682D727-208C-4E6A-B101-B6341D40D222}:\r\n\r\n \xc3\xbd\xcc\xe5\xd7\xb4\xcc\xac . . . . . . . . . . . . : \xc3\xbd\xcc\xe5\xd2\xd1\xb6\xcf\xbf\xaa\r\n \xc1\xac\xbd\xd3\xcc\xd8\xb6\xa8\xb5\xc4 DNS \xba\xf3\xd7\xba . . . . . . . : \r\n' res1=subprocess.check_output("ls",shell=True) print(res1) >>>'ls' ????????????????????????е???? ????????????? Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/untitled/day6/subprocess模块.py", line 24, in <module> res1=subprocess.check_output("ls",shell=True) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\subprocess.py", line 336, in check_output **kwargs).stdout File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\lib\subprocess.py", line 418, in run output=stdout, stderr=stderr) subprocess.CalledProcessError: Command 'ls' returned non-zero exit status 1.
# popen 实际上,subprocess模块中只定义了一个类: Popen;上面那些方法,底层都是封装的subprocess.Popen
构造函数如下:
subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
例子
>>> p=subprocess.Popen("ifconfig|grep 10",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
>>> p.stdout.read()
' inet addr:10.123.16.27 Bcast:10.123.16.255 Mask:255.255.255.0\n collisions:0 txqueuelen:1000 \n'
>>> p
<subprocess.Popen object at 0x7f759c16e610>
>>> res=subprocess.Popen("ifconfigfaf|grep 10",shell=True,stdout=subprocess.PIPE)
>>> /bin/sh: ifconfigfaf: command not found
>>>res=sub.stdout.read()
>>>''
>>> res=subprocess.Popen("ifconfigfaf|grep 10",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.stdout.read()
''
>>> res.stderr.read()
'/bin/sh: ifconfigfaf: command not found\n'
>>> res=subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.stdout.read()
'hello\n'
>>> res=subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> print(res.poll())
None
>>> print(res.poll())
None #还没有执行完成
>>> res.poll()
File "<stdin>", line 1
res.poll()
^
IndentationError: unexpected indent
>>> print(res.poll())
0 #执行完成了
>>> res=subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.wait()
0 #需等待10s
>>> res=subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res.terminate() #杀掉启动的进程
>>> res.stdout.read()
''
import subprocess
res=subprocess.Popen(['python'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
p=res.stdin.write(b"print(1)")
print(p)
q=res.communicate()
print(q)
>>>8
(b'1\r\n', b'')
res=subprocess.Popen(['python'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
p1=res.stdin.write(b"print(1)")
p2=res.stdin.write(b"print(2)")
p3=res.stdin.write(b"print(3)")
p4=res.stdin.write(b"print(4)")
q=res.communicate()
print(q)
>>>(b'', b' File "<stdin>", line 1\r\n print(1)print(2)print(3)print(4)\r\n ^\r\nSyntaxError: invalid syntax\r\n')
需要交互的命令示例
import subprocess obj=subprocess.Popen(["python"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) obj.stdin.write(b'print 1 \n') obj.stdin.write(b'print 2 \n') obj.stdin.write(b'print 3 \n') obj.stdin.write(b'print 4 \n') out_error_list=obj.communicate(timeout=10) print(out_error_list) >>>(b'', b' File "<stdin>", line 1\r\n print 1 \r\n ^\r\nSyntaxError: Missing parentheses in call to \'print\'\r\n')
subprocess实现sudo 自动输入密码
import subprocess def mypass(): mypass='123' return mypass echo=subprocess.Popen(['echo',mypass()],stdout=subprocess.PIPE) sudo=subprocess.Popen(['sudo','-S','iptables','-L'],stdin=echo.stdout,stdout=subprocess.PIPE) end_of_pipe=sudo.stdout print("Password ok\n Iptables Chains %s" % end_of_pipe.read())
2.面向对象编程
OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率,另外,基于面向对象的程序可以使他人更加理解你的代码逻辑,从而使团队开发变得更从容。
面向对象的三大特性:封装、继承、多态
封装:1.防止数据被随意修改;2.使外部程序不需要关注对象内部的构造,只需要通过此对象对外提供的接口进行直接访问即可;
继承:通过父类——》子类的方式以最小代码量的方式实现不同角色的共同点和不同点的同时存在;
多态:一个接口,多种实现;
函数编程与面向对象编程规则:
1.写重复代码是非常不好的低级行为;
2.你写的代码需要经常变更;
类的定义
class Dog(object): def __init__(self,name): #构造函数;构造方法==初始化方法 self.NAME=name def sayhi(self): #类的方法 print("hello,I am a dog.my name is",self.NAME) d1=Dog("alex") #Dog(d,"alex") 实例化后产生的对象叫实例 d2=Dog("kobe") d2.sayhi()
class Role(object): def __init__(self,name,role,weapon,life_value=100,money=15000): self.name=name self.role=role self.weapon=weapon self.life_value=life_value self.money=money def shot(self): print("%s is shooting..." % self.name) def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gun_name): print("%s just bought %s" % (self.name,gun_name)) self.weapon=gun_name r1=Role("alex","police","AK47") #生成一个角色 r2=Role("jack","terrorist","B22") #生成一个角色 r1.shot() r2.got_shot() r2.buy_gun("B46") print(r2.weapon) ********** alex is shooting... ah...,I got shot... jack just bought B46 B46
类的属性
公有属性
在类里直接定义的属性即是公有属性;
class Role(object): nationality="JP" #公有属性 def __init__(self,name,role,weapon,life_value=100,money=15000): self.name=name self.role=role self.weapon=weapon self.life_value=life_value self.money=money self.__heart="Normal" #私有属性
私有属性
__private_attr_name=value
def get_heart(self): #对外部提供只读访问接口
return self.__heart
r1._Role__heart #强制访问私有属性
class Role(object): def __init__(self,name,role,weapon,life_value=100,money=15000): self.name=name self.role=role self.weapon=weapon self.life_value=life_value self.money=money self.__heart="Normal" #私有属性 def shot(self): print("%s is shooting..." % self.name) def get_heart(self): return self.__heart def got_shot(self): print("ah...,I got shot...") self.__heart="Die" print(self.__heart) def buy_gun(self,gun_name): print("%s just bought %s" % (self.name,gun_name)) self.weapon=gun_name r1=Role("alex","police","AK47") #生成一个角色 r2=Role("jack","terrorist","B22") #生成一个角色 print(r1.name) print(r1.get_heart()) print(r1.got_shot()) #内部访问 print(r1._Role__heart) #强制访问属性 r1.__heart ****** alex Normal ah...,I got shot... Die Die Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/untitled/day6/私有属性.py", line 37, in <module> r1.__heart AttributeError: 'Role' object has no attribute '__heart'
析构方法
实例销毁时,执行该函数;
def __del__(self): print("del......run...")
继承
它可以使用现有类的所以功能,并在无需重新编写原来的类的情况下对这些功能进行扩展;
通过继承创建的新类称为“子类”或“派生类”;
被继承的类称为“基类”、“父类”或“超类”
继承的过程就是从一般到特殊的过程;要实现继承,可以通过继承和组合来实现;
继承概念的实现方式主要有2类:
实现继承:指使用的属性和方法而无需额外编码的能力;
接口继承:指仅使用属性和 方法的名称,但是子类必须提供实现的能(子类重构父类方法);
抽象类仅定义将有子类创建的一般属性和方法;
OOP开发范式大致为:划分对象——》抽象类——》将类组织成为层次化结构(继承和合成)——》用类与实例进行设计和实现几个阶段。
class Person(object): def __init__(self,name,age): self.name=name self.age=age self.sex="normal" def talk(self): print("person is talking...1") class WhitePerson(Person): pass class BlackPerson(Person): def __init__(self,name,age,strength):#先继承,再重构 Person.__init__(self,name,age) self.strength=strength print(self.name,self.age,self.sex) def talk(self): Person.talk(self) print("black person is blala...") def walk(self): print("is walking....") b= BlackPerson("wei er smith",30,"strong") b.talk() b.walk()
经典类与新式类
class Person(object): #新式类 pass class Person: #经典类 pass #多继承时继承顺序的区别 class A: def __init__(self): self.n="A" class B(A): pass # def __init__(self): # self.n="B" class C(A): # pass def __init__(self): self.n="C" class D(B,C): pass # def __init__(self): # self.n="D" d=D() print(d.n) # python 3 全都是广度查找 # python 2 经典类是深度查找,新式类是广度查找
多态
class Animal: def __init__(self,name): self.name = name def talk(self): raise NotImplementedError("Subclass must implement abdtract method") class Cat(Animal): def talk(self): return "Meow!" class Dog(Animal): def talk(self): return "Woof! Woof!" d = Dog("d1") c = Cat("C1") def animal_talk(obj): print(obj.talk()) animal_talk(d) animal_talk(c)
静态方法
只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性
class Dog(object): def __init__(self,name): self.name = name @staticmethod #实际上跟类没什么关系,相当于一个函数 def eat(): print("%s is eating %s" %('ame','food')) d = Dog("ChenRonghua") d.eat()
类方法
只能访问类变量,不能访问实例变量
class Dog(object): # n=333 name="huazai" def __init__(self,name): self.name=name # self.n=333 @classmethod def eat(self): print("%s is eating %s" %(self.name,'dd')) def talk(self): print("%s is talking" % self.name) d = Dog("ChengRonghua") d.eat()
属性方法
把一个方法变成一个静态属性
class Dog(object): # n=333 name="huazai" def __init__(self,name): self.name=name self.__food= None # @classmethod @property #attribute def eat(self): print("%s is eating %s" %(self.name,self.__food)) @eat.setter def eat(self,food): print("set to food:",food) self.__food = food def talk(self): print("%s is talking" % self.name) d = Dog("ChengRonghua") # d.eat() d.eat d.eat="baozi" d.eat --------结果------- ChengRonghua is eating None set to food: baozi ChengRonghua is eating baozi
3.类的特殊成员方法
1. __doc__ 表示类的描述信息
class Dog(object): '''这个类是描述狗对象的''' def __init__(self,name): self.name=name print(Dog.__doc__) ————结果———— 这个类是描述狗对象的
2. __module__ 和 __class__
__module__ 表示当前操作的对象在哪个模块
__class__ 表示当前操作的对象的类是什么
class C: def __init__(self): self.name = 'navy'
from lib.aa import C obj=C() print(obj.__module__) print(obj.__class__)
3. __init__ 构造方法,通过类创建对象时,自动触发执行
4. __del__ 析构方法,当对象在内存中被释放时,自动触发执行
#此方法一般无需定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行;所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
5. __call__对象后面加括号,触发执行
#构造方法的执行是由创建对象触发的,即:对象=类名();而对象__call__方法的执行是由对象后的括号触发的,即:对象()或类()()
class Dog(object): def __init__(self,name): self.name=name def __call__(self,*args,**kwargs): print("running call",args,kwargs) d=Dog("ChenRonghua") d(1,2,3,name=333) ------结果------ running call (1, 2, 3) {'name': 333}
6. __dict__ 查看类或对象中的所有成员
class Province: '''这个类是定义省内人口和收入''' country = 'China' def __init__(self,name,count): self.name=name self.count=count def func(self,*args,**kwargs): print(func) # 获取类的成员,即:静态字段、方法 print(Province.__dict__) #打印类里的所有属性,不包括实例属性 obj1 = Province("HeBei",10000) print(obj1.__dict__) #打印实例属性,不包括类属性 obj2 = Province("HeNan",3888) print(obj2.__dict__) ------结果------ {'__module__': '__main__', '__doc__': '这个类是定义省内人口和收入', 'country': 'China', '__init__': <function Province.__init__ at 0x01E652B8>, 'func': <function Province.func at 0x01E651E0>, '__dict__': <attribute '__dict__' of 'Province' objects>, '__weakref__': <attribute '__weakref__' of 'Province' objects>} {'name': 'HeBei', 'count': 10000} {'name': 'HeNan', 'count': 3888}
7. __str__ 如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值
class Dog(object): def __init__(self,name): self.name=name def __call__(self,*args,**kwargs): print("running call",args,kwargs) def __str__(self): return "<obj:%s>" %self.name d=Dog("ChenRonghua") print(d) ------结果------ <obj:ChenRonghua>
8.__getitem__、__setitem__、__delitem__ 用于索引操作,如字典,以上分别表示获取,设置,删除数据
class Foo(object): def __init__(self): self.data={} def __getitem__(self, key): print('__getitem__',key) return self.data.get(key) def __setitem__(self, key, value): print('__setitem__',key,value) self.data[key]=value def __delitem__(self, key): print('__delitem__',key) obj = Foo() obj['name']='alex' print(obj['name']) print(obj.data) result = obj['k1'] #自动触发执行__getitem__ obj['k2'] = 'alex' #自动触发执行__setitem__ del obj['k1'] ------结果------ __setitem__ name alex __getitem__ name alex {'name': 'alex'} __getitem__ k1 __setitem__ k2 alex __delitem__ k1
9. __new__\ __metaclass__
1 class Foo(object): 2 3 def __init__(self,name): 4 self.name=name 5 6 obj = Foo("alex") 7 print(type(obj)) 8 print(type(Foo)) 9 10 ------结果------ 11 <class '__main__.Foo'> 12 <class 'type'>
上述代码中,obj是通过Foo类实例化的对象,其实,不仅obj是一个对象,Foo类本身也是一个对象,因为在Python中一切事物皆对象。按此理论,obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的构造方法创建。所以,obj对象是Foo类的一个实例,Foo类对象是type类的一个实例,即:Foo类对象,是通过type类的构造方法创建。
那么创建类就可以有2种方式:
a).普通方式
class Foo(object): def func(self): print("hello alex")
b).特殊方式
def func(self): print("hello %s" %self.name) def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo',(object,),{'talk':func,'__init__':__init__}) #type第一个参数:类名 #type第二个参数:当前类的基类 #type第三个参数:类的成员或方法 f = Foo("Chrn",22) f.talk() print(type(Foo)) ------结果------ hello Chrn <class 'type'>
4. 反射
通过字符串映射或修改程序运行时的状态、属性、方法,有以下4种方法:
hasattr(obj,name_str) 判断一个对象obj里是否有对应的name_str字符串
getattr(obj,name_str) 根据字符串去获取obj对象里的对应方法的内存地址
setattr(obj,'y',z) 相当于 obj.y=z
delattr(x,y)
def buck(self): print("%s is yelling..."%self.name) class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating..."%self.name,food) d= Dog("wangcai") choice = input(">>:").strip() if hasattr(d,choice): attr=getattr(d,choice) # func("baozi") setattr(d,choice,"Ronghua") else: # setattr(d,choice,buck) # d.talk(d) delattr(d,choice) setattr(d,choice,22) print(getattr(d,choice)) print(d.name)
5. SOCKET
socket是TCP/IP的一个封装,对用户来说它只是一堆接口,socket是一个软件抽象层,它不负责发送数据,而是处理数据,Socket有分BS和CS架构。它们本质上都是一个客户端和服务端之间的数据通信。
import socket ip_port=('127.0.0.1',9999) s= socket.socket() #买手机 #利用创建出来的对象来绑定:买手机卡 #因为这个对象是已经封装号 TCP 协议的 s.bind(ip_port) #开机 s.listen(5) #等待电话 # conn 服务端跟客户端连接的通讯 conn,addr=s.accept() #每次听电话只能跟一个人通信,然后另一条线会挂着 #收消息 recv_data= conn.recv(1024) print("--------",type(recv_data)) #发消息 send_data=recv_data.upper() conn.send(send_data) #挂电话 conn.close()
import socket ip_port=('127.0.0.1',9999) s=socket.socket() s.bind(ip_port) s.listen(5) while True: conn,addr =s.accept() while True: try: recv_data=conn.recv(1024) if len(recv_data)==0:break send_data=recv_data.upper() print(send_data) conn.send(send_data) except Exception: break conn.close()
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:027class_part1
下一篇:爬虫之MongoDB
- Python之对象持久化笔记 2019-08-13
- python3 enum模块的应用 2019-08-13
- 利用python自动生成verilog模块例化模板 2019-08-13
- python之函数、面向对象 2019-08-13
- Python random模块(以后用到一个再更新一个) 2019-07-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash