模块三—面向对象

2018-06-18 00:43:27来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

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
View Code

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
View Code

常用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
View Code
>>> retcode =subprocess.call(["ls","-M"])
ls: invalid option -- 'M'
Try `ls --help' for more information.
>>> retcode
2
View Code

 

#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
View Code

#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或批处理文件。")
View Code

#getoutput   接收字符串格式命令,并返回结果

res=subprocess.getoutput("ls /bin/ls")
print(res)

>>>'ls' 不是内部或外部命令,也不是可运行的程序或批处理文件。
View Code

#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.
View Code

 

# 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')
View Code

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())
View Code

 

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'
View Code

 

析构方法


实例销毁时,执行该函数;

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()
View Code

 

经典类与新式类

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  经典类是深度查找,新式类是广度查找
View Code

 

多态

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)
View Code

 

静态方法

  只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性

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'
lib/aa.py
from lib.aa import  C

obj=C()
print(obj.__module__)
print(obj.__class__)
BB

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}
View Code

 

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}
View Code

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>
View Code

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
View Code

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'>
View Code

上述代码中,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")
View Code

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'>
View Code

 

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)
View Code

 

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()
socket服务端(基础版)
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()
socket服务端(优化版)

 

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:027class_part1

下一篇:爬虫之MongoDB