python基础知识3(对象、socket)

面向对象函数

封装:

class Role(object):
    n='123'#类参数:大家都有的属性,节省内存
    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 __del__(self):#析构函数:在实例释放、销毁的时候自动执行的,通常用于一些收尾工作,如关闭一些数据库连接、关闭打开的临时文件等
        print('%s 彻底死了!'%self.name)

    def shot(self):#类方法 功能(动态属性)
        print("shooting...")

    def got_shot(self):
        print("ah...,I got shot...")

    def __buy_gun(self, gun_name):#私有方法:外面不可调用
        print("just bought %s" % gun_name)


r1 = Role('Alex', 'police', 'AK47') #生成一个角色
r1.n='haha'
print('r1:',r1.n)
r2 = Role('Jack', 'terrorist', 'B22')  #生成一个角色
print('r2:',r2.n)
Role.n='abc'
print('类参数改后:r1:%s;r2:%s'%(r1.n,r2.n))

继承:

#class Peple(object):#新式类
class Peple:#经典类
    def __init__(self,name):
        self.name=name
        self.friend=[]
    def sleep(self):
        print('%s sleep...'%self.name)

    def eat(self):
        print('%s eat...'%self.name)

class Relation(object):
    def make_friends(self,obj):
        print('%s make friends with %s'%(self.name,obj.name))
        self.friend.append(obj)#传的是对象内存,而不是值
class Man(Peple,Relation):#多继承
    def __init__(self,name,age):#添加实例参数
        # Peple.__init__(self,name)#经典类
        super(Man,self).__init__(name)#新式类
        self.age=age
        print('%s age:%s'%(self.name,self.age))
    def work(self):
        print('%s work...'%self.name)

    def make_monkey(self):#调用父类函数
        Peple.sleep(self)
        print('%s make_money...'%self.name)

class Woman(Peple):#继承Peple
    def shopping(self):
        print('%s shopping...'%self.name)

m=Man('haha',3)
m.eat()
m.make_monkey()
w=Woman('enen')
w.shopping()
m.make_friends(w)
w.name='yoyo'
print(m.friend[0].name)

继承实例(多继承):经典类和新式类都是统一按广度优先来继承的

class School(object):
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr
        self.student=[]
        self.staff=[]

    def enroll(self,stu_obj):
        print('%s enroll student[%s]'%(self.name,stu_obj.name))
        self.student.append(stu_obj)

    def hire(self,staff_obj):
        print('%s hire staff[%s]'%(self.name,staff_obj.name))
        self.staff.append(staff_obj)

class SchoolMenber(object):
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def tell(self):
        print('[%s] is telling... '%self.name)

class Teacher(SchoolMenber):
    def __init__(self,name,age,sex,salary,course):
        super(Teacher,self).__init__(name,age,sex)
        self.salary=salary
        self.course=course

    def tell(self):
        print('''
        info of Teacher[%s]
        TeacherName:%s
        TeacherAge:%s
        TeacherSex:%s
        TeacherSalary:%s
        TeacherCourse:%s
        '''%(self.name,self.name,self.age,self.sex,self.salary,self.course))

    def teach(self):
        print('teacher [%s] teach course[%s]'%(self.name,self.course))

class Student(SchoolMenber):
    def __init__(self,name,age,sex,stu_id,grade):
        super(Student,self).__init__(name,age,sex)
        self.stu_id=stu_id
        self.grade=grade

    def tell(self):
        print('''
        info of Student[%s]
        StudentName:%s
        StudentAge:%s
        StudentSex:%s
        StudentStu_id:%s
        StudentGrade:%s
        ''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))

    def pay_tuition(self,amount):
        print('student[%s] has pay_tuition $[%s]'%(self.name,amount))

school=School('川化','青白江')
t1=Teacher('YoYo',35,'F',5000,'Python')
t2=Teacher('QQ',40,'M',8000,'go')

s1=Student('haha',15,'F',25,'Python')
s2=Student('enen',19,'M',31,'go')

t1.tell()
#输出:
'''
        info of Teacher[YoYo]
        TeacherName:YoYo
        TeacherAge:35
        TeacherSex:F
        TeacherSalary:5000
        TeacherCourse:Python
'''
s1.tell()
#输出:
'''
        info of Student[haha]
        StudentName:haha
        StudentAge:15
        StudentSex:F
        StudentStu_id:25
        StudentGrade:Python
'''
school.enroll(s1)
#输出:川化 enroll student[haha]
school.enroll(s2)
#输出:川化 enroll student[enen]
school.hire(t1)
#输出:川化 hire staff[YoYo]
school.hire(t2)
#输出:川化 hire staff[QQ]

school.student[0].pay_tuition(500)
#输出:student[haha] has pay_tuition $[500]
print(school.staff)
#输出:[<__main__.Teacher object at 0x00000000027FAE80>, <__main__.Teacher object at 0x00000000027FAEB8>]

for staff in school.staff:
    staff.teach()
#输出:
'''
teacher [YoYo] teach course[Python]
teacher [QQ] teach course[go]
'''

多态:实现接口重用

class Animal(object):
    def __init__(self,name):
        self.name=name

    @staticmethod
    def animal_talk(obj):
        obj.talk()

class Dog(Animal):
    def talk(self):
        print('wang wang')

class Cat(Animal):
    def talk(self):
        print('miao miao')

d=Dog('haha')
d.talk()
#输出:wang wang
c=Cat('enen')
c.talk()
#输出:miao miao
Animal.animal_talk(d)
#输出:wang wang
Animal.animal_talk(c)
#输出:miao miao

静态方法、类方法、属性方法

class Person(object):
    n='enen'
    def __init__(self,name):
        self.name=name

    @staticmethod
    def eat(food):
        #静态方法已经和类没有关系了
        #只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性
        print('eat %s'%food)

    @property#属性方法就是把一个方法变成一个静态属性
    def sleep(self):
        print('%s is sleeping...'%self.name)

    @sleep.setter
    def sleep(self,new_name):
        print('%s change to %s'%(self.name,new_name))
        self.name=new_name

    @sleep.deleter
    def sleep(self):
        print('delete sleep...')

    @classmethod
    def talk(self,talking):
        #类方法只能访问类变量,不能访问实例变量
        print('%s talk "%s"'%(self.n,talking))

person=Person('haha')
person.eat('包子')
person.talk('hhhhhhh')
person.sleep='yoyo'
person.sleep
del person.sleep#触发 @sleep.deleter
#输出:
'''eat 包子
enen talk "hhhhhhh"
haha change to yoyo
yoyo is sleeping...
delete sleep...
yoyo is sleeping...
'''

类的特殊成员方法

__doc__:表示类的描述信息

class Fo(object):
    '''描述类信息'''

    def func(self):
        pass

print(Fo.__doc__)
#输出:描述类信息

__module__ 和 __class__
__module__表示当前操作的对象在那个模块
__class__表示当前操作的对象的类是什么

class C:
    def __init__(self):
        self.name = 'wupeiqi'
from lib.aa import C
obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

__call__对象后面加括号,触发执行

class Foo:
    def __init__(self):
        pass
    def __call__(self, *args, **kwargs):
        print ('running...',args,kwargs)
 
obj = Foo() # 执行 __init__
obj()       # 执行 __call__

__dict__查看类或对象中的所有成员
__str__如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值

class Fo(object):
    n='enen'
    def __init__(self,name):
        self.name=name
    def func(self):
        pass
    def __str__(self):
        return 'obj:%s'%self.name
print(Fo.__dict__)#打印类里的所有属性,不包括实例对象
#输出:{'__module__': '__main__', 'n': 'enen', '__init__': <function Fo.__init__ at 0x00000000021EA950>, 'func': <function Fo.func at 0x00000000021EA8C8>, '__call__': <function Fo.__call__ at 0x00000000021EAC80>, '__dict__': <attribute '__dict__' of 'Fo' objects>, '__weakref__': <attribute '__weakref__' of 'Fo' objects>, '__doc__': None}
print(Fo('haha').__dict__)#打印所有实例对象,不包括类属性
#输出:{'name': 'haha'}
print(Fo('haha'))
#输出:obj:haha

__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):
    def __getitem__(self, key):
        print('__getitem__',key)
 
    def __setitem__(self, key, value):
        print('__setitem__',key,value)
 
    def __delitem__(self, key):
        print('__delitem__',key)
 
obj = Foo()
result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'alex'   # 自动触发执行 __setitem__
del obj['k1']   

**注:**类 是由 type 类实例化产生

def func(self):
    print('hello[%s]this is func!'%self.name)

def __init__(self,name):
    self.name=name

f=type('Foo',(object,),{'welcome':func,'__init__':__init__})
h=f('haha')
h.welcome()

反射

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

def talk(self):
    print('%s is talking...'%self.name)

class Foo(object):
    def __init__(self,name):
        self.name=name

    def eat(self,food):
        print('%s is eating %s'%(self.name,food))

f=Foo('haha')
a='eat'
b='talking'
c='name'
'''
hasattr(obj,name_str),判断一个对象obj里是否有对应的name_str字符串的方法
'''
print(hasattr(f,a))
#输出:True
print(hasattr(f,b))
#输出:False
print(hasattr(f,c))
#输出:True
'''
getattr(obj,name_str),根据字符串去获取obj对象里的对应的方法的内存地址
'''
print(getattr(f,a))
#输出:<bound method Foo.eat of <__main__.Foo object at 0x0000000001E08F98>>
getattr(f,a)('包子')
#输出:haha is eating 包子
print(getattr(f,c))
#输出:haha

'''
setattr(obj,name_str,z),在obj对象里根据字符串创建新的方法,z代表已有的方法或实例参数
'''
setattr(f,b,talk)
f.talking(f)
#输出:haha is talking...

setattr(f,b,22)
print(f.talking)
#输出:22

'''
delattr(obj,name_str),删除obj对象里对应的字符串方法或实例参数
'''
delattr(f,a)
f.eat('馒头')
#输出:报错:AttributeError: eat

delattr(f,c)
f.name
#输出:报错:AttributeError: 'Foo' object has no attribute 'name'

动态导入模块

image.png

import importlib
c=importlib.import_module('day6.cs')

a=c.Role('haha','police','ak')

异常

异常处理

正常出错:

a={'1':'a'}
a[2]
#报错:KeyError: 2
b=[1,2,3]
b[3]
#报错:IndexError: list index out of range

错误处理:

try:
    a[2]
except KeyError as e:
    print (e)
#输出:2
try:
    b[3]
except IndexError as e:
    print (e)
#输出:list index out of range

严密处理:

try:
    a[2]
    b[3]
except (KeyError,IndexError) as e:
    print (e)
except Exception as mg:
    print ('其他错误')
else:print ('一切正常')
finally:print ('不管有无错误都会执行')
#输出:
'''
2
不管有无错误都会执行
'''

自定异常

class HahaError(Exception):
    def __init__(self,msg):
        self.massage=msg

    def __str__(self):
        return '错误类型:Haha'

try:
    raise HahaError('连接数据库。。。')
except HahaError as msg:
    print (msg)
#输出:错误类型:Haha

Socket编程

建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。
image.png

基本的socket实现

socket_server:

import socket

server=socket.socket()
server.bind(('localhost',1234))#绑定要监听端口
server.listen(3)#监听,允许多少连接等待
print('开始等待指定端口号连接口号')
while True:
    con,addr=server.accept()#连接进来。。。
    #con就是客户端连过来而在服务器为其生成的一个连接实例
    print(con,addr)
    print('连接进来。。。')
    while True:
        data=con.recv(1024)
        print('recv:',data.decode())
        if not data:
            print('client has closed')
            break
        con.send(data)
server.close()

socket_client:

import socket

client=socket.socket()#声明socket类型,同时生成socket连接对象
client.connect(('localhost',1234))
while True:
    input_data=input('>').strip()
    if len(input_data)==0:continue
    client.send(input_data.encode('utf-8'))
    data=client.recv(1024)
    print('rece:',data.decode())
client.close()

使用socket实现简单ssh功能

server:

import socket,os

server=socket.socket()
server.bind(('localhost',6666))
server.listen()
while True:
    con,addr=server.accept()
    print('已连接:',addr)
    while True:
        cmd_data = con.recv(1024)
        print('接收指令:',cmd_data.decode())
        if not cmd_data:
            print('客服端以断开')
            break
        cmd_res=os.popen(cmd_data.decode()).read()#运行命令
        if len(cmd_res)==0:#有可能会报错,就造一个cmd_res数据,保证通话继续
            cmd_res='执行结果为空'
        cmd_res_size=len(cmd_res)
        print('cmd_res_size:',cmd_res_size)
        con.send(str(cmd_res_size).encode('utf-8'))#返回执行结果的长度
        print('cmd_res:',cmd_res)
        # client_ack=con.recv(1024)#如果连续发送的数据发生粘包,就使用这种处理方法
        # print('client_ack:',client_ack.decode())
        con.send(cmd_res.encode('utf-8'))

server.close()

client:

import socket
client=socket.socket()
client.connect(('localhost',6666))
while True:
    cmd_data=input('请输入指令:').strip()
    if len(cmd_data)==0:continue#如果输入字符为空,则重新输入
    client.send(cmd_data.encode('utf-8'))
    cmd_res_size=client.recv(1024)#接收运行结果的长度
    print('cmd_res_size:',int(cmd_res_size.decode()))
    # client.send('cmd_res_size已收到!'.encode('utf-8'))#防止连续接收的数据发生粘包
    receive_size=0
    while receive_size!=int(cmd_res_size.decode()):#存在运行结果太长,一次接收不完,则分多次接收,判断接收的长度不等于总长度,则继续接收
        cmd_res = client.recv(1024)
        print('运行结果如下:', cmd_res.decode())
        receive_data_size=len(cmd_res.decode())
        receive_size+=receive_data_size

    else:print('接收完毕')


client.close()

使用socket实现ftp功能

server:

import socket,os,hashlib

server=socket.socket()
server.bind(('localhost',8888))
server.listen()
while True:
    con,addr=server.accept()
    print('已连接:',addr)
    while True:
        data=con.recv(1024).decode()
        cmd,filename= data.split()
        m=hashlib.sha256()
        print('接收指令:',cmd)
        if not data:
            print('客服端以断开')
            break
        if os.path.isfile(filename):
            f=open(filename,'rb')
            file_size=os.stat(filename).st_size
            con.send(str(file_size).encode('utf-8'))
            print('file_size:',file_size)
            con.recv(1024)
            for line in f:
                con.send(line)
                m.update(line)
            con.send(m.hexdigest().encode('utf-8'))
            print('sha256加密码:',m.hexdigest())
            f.close()
server.close()

client:

import socket,hashlib
client=socket.socket()
client.connect(('localhost',8888))
m=hashlib.sha256()
while True:
    cmd_data=input('请输入指令:').strip()
    if len(cmd_data)==0:continue#如果输入字符为空,则重新输入
    client.send(cmd_data.encode('utf-8'))
    cmd,filename=cmd_data.split()
    if cmd=='get':
        file_size=client.recv(1024)#接收运行结果的长度
        print('file_size:',int(file_size.decode()))
        client.send('file_size已收到!'.encode('utf-8'))#防止连续接收的数据发生粘包
        receive_size=0
        f=open(filename+'new','wb')
        while receive_size!=int(file_size.decode()):#存在运行结果太长,一次接收不完,则分多次接收,判断接收的长度不等于总长度,则继续接收
            if int(file_size.decode())-receive_size>1024:#判断所剩文件大小是否小于1024,不小于继续接收,小于就只接收剩余大小文件,以便最后一次接收和sha256密码发生粘包
                size=1024
            else:
                size=int(file_size.decode())-receive_size
                print('最后一次size:',size)
            cmd_line = client.recv(size)
            f.write(cmd_line)
            receive_data_size=len(cmd_line)
            receive_size+=receive_data_size
            m.update(cmd_line)
        else:
            print('接收完毕')
            receive_m=client.recv(2014).decode()#接收服务端发送的密码
            f.close()
            print('receive_m:',receive_m)
            print('m:',m.hexdigest())#自己的密码

client.close()

Socket实现多线程TCP网络服务

server:

import socketserver

class MyTcpHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                print('请求IP:',self.client_address[0])
                self.data=self.request.recv(1024)
                print('recv:',self.data.decode())
                self.request.send(self.data.upper())
            except ConnectionResetError as e:
                print('error:',e)
                break
if __name__ == '__main__':
    host,addr=('localhost'),1234
    server=socketserver.ThreadingTCPServer((host,addr),MyTcpHandler)
    server.serve_forever()

client同基本的socket实现中client

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值