Python基础(3)-面向对象

第七章 面向对象

1 什么是面向对象

面向对象是一种抽象化的编程思想,是相对于面向过程而言的。面向对象将功能等通过对象来实现的,将功能封装进对象,让对象去实现其中具体的细节。一切皆为对象万物皆为对象。
【官方解释】:面向对象是软件开发方法,一种编程范式
举例来说,洗衣服的两种方法:

1、手洗:拿个桶,接水,将衣服泡湿,倒洗衣液,洗啊洗啊洗,倒掉一次两次三次水直到泡泡洗干净,拧干,晾衣服
2、机洗:扔衣服到洗衣机,倒洗衣液启动洗衣机,等待洗衣机洗好晾衣服
对比这两个,洗衣机洗衣服更加简单,洗衣服完成了手机需要的一二三四五N个步骤
思考:机洗,只需要找到一台洗衣机,加入简单操作就可以完成洗衣服的工作,而不需要关心洗衣机内部发生了什么事情。

面向过程强调的是过程,关注步骤、动作,我是执行者
面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么事。

Python是同时支持面向过程和面向对象的编程语言!

2、面向对象的三大特征:封装,继承、多态
1.封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别【公有、私有】,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体
好处:将变化隔离、便于使用、提高复用性、提高安全性
原则:将不需要对外提供的内容隐藏起来,把属性隐藏,提供公共方法对其访问
2.继承子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和行为;或子类从父类继承方法,使得子类具有父类相同的行为。
提高代码复用性;继承是多态的前提
子类中所有的构造函数都会默认访问父类中的空参数的构造函数,默认第一行有super;若无空参数构造函数,子类中需指定;另外,子类构造函数中可自己用this指定自身的其他构造函数。
3.多态是指不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式。 ==>官方解释
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象
好处:提高了程序的扩展性
弊端:当父类引用指向子类对象时,虽提高了扩展性,但只能访问父类中具备的方法,不可访问子类中的方法:即访问的局限性。
前提:实现或继承关系;覆写父类方法。

2 概念

2.1 类!

类是抽象的概念,指的是对事物的某些描述信息, 通俗:类就是一个模板.

1:类是抽象的概念,对事物的某些描述信息; --[类就是一个模板, 老师给了大家一个表格:姓名、性别、毕业院校等]
2:(抽象)当你听到一个名词时,不能立马想到他的具体模样,这就是类.

定义在类中的函数,就叫做方法,方法后的第1个参数是self
方法的语法:跟函数类似,只不过多个参数self
定于类的语法如下:

class 类名:
	def 方法名(self):
		代码1
		代码2
		...
	# 其他方法...

eg:定义汽车类

class Car:
    def run(self):
        print("汽车能跑起来...")
# 当定义了类后,执行没有直接的效果,需具体化后才有执行效果

几种定义类的方法:

class Teacher: #Python3用法
    pass
    
class Student(): #可以兼容Python2
    pass
    
class Phone(object): #建议使用
    pass

2.2 对象!

对象是类的实例化,是具体的概念,是实实在在存在的个体,通俗:对象是通过模板创建出来的东西.
① 创建对象语法:对象名 = 类名() # 后面空括号
② 调用方法语法:对象名.方法名()

eg:调用上方定义的汽车类

# 1.创建对象,car为对象名
car=Car()
# 2.调用方法
car.run()

[变量名]命名对象名的规则:所有字母均小写,单词与单词之间使用下划线连接;
对象是具体的,看得见摸得着,有了对象及调用方法后,有执行结果

2.3 self关键字

self也是Python内置的关键字之一,其指向了对象实例本身【对象自己】
注意:在类内部使用[self.属性名] 调用属性,使用self.[方法名]调用方法。

# 1.定义学生类,输出self
class Student:
    def study(self):
        print("=======================")
        print("正在努力学习")
        print("=================",self)
        print("=======================")

    # 睡觉类
    def sleep(self):
        # 调用当前对象的方法
        self.study()
# 调用方法
stu=Student()
print(stu)

stu.study()

3 对象属性

什么是属性:
属性在面向对象中,可以使用变量来表示
属性可以在类内部、类外部都进行获取与使用
类外面访问属性,语法如下:
(1)添加属性:对象名.属性名 = 值
(2)获取属性:对象名.属性名

class Car():
    def run(self):
        print("汽车跑啊跑")
# 1.创建对象
car=Car()
# 2.添加属性
car.color="red"
car.number=4
# 3.获取属性
print(f"颜色:{car.color}")
print(f"轮胎数:{car.number}")

类内部访问属性:
语法:self.属性

class Car():
    def run(self):
        print("汽车跑啊跑")
    # 定义方法
    def show(self):
    	# 内部获取值
        print(f"颜色:{self.color}")
        print(f"轮胎数:{self.brand}")
# 1.创建对象
car=Car()
# 2.外部设定值
car.color="back"
car.brand="BMW"
# 3.获取属性
car.show()

4 魔法方法

魔法方法指的是:可以给Python类增加魔力的特殊方法。有两个特点:
(1)总是被双下划线所包围;
(2)在特殊时刻会被自动调用,不需要开发者手动去调用。
魔法方法语法:__魔法方法名__()

__init__(self [, ...]):构造器,当一个对象被初始化创建时,会被自动调用。
__str__(self):输出对象名时,若不想直接输出内存地址值,可重写str()方法。
__del__(self):当一个对象被删除或销毁时,会被自动调用。

4.1 无参__init__() 方法!

在Python中,当新创建一个对象时,则会自动触发 __init__() 魔法方法
__init__(self [, ...]):构造器,当一个对象被初始化创建时,会被自动调用。
无参__init__() 方法语法:

class 类名:
	def __init__(self):
		代码
		...
class Student:
    def __init__(self):
        print("执行了init...")
# 创建对象,创建对象时会自动调用 init 方法
stu=Student() 

案例:

# 1.定义类:默认设置属性
class MyCar:
    def __init__(self):
        self.color="black"
        self.number=3
    def func(self):
        print("===============")
        print(f"颜色:{self.color}")
        print(f"轮胎数:{self.number}")
        print("===============")

# 2.在类的外部访问属性
my_car=MyCar()
print(my_car.color)
print(my_car.number)

# 3.类内部访问属性
my_car.func()

4.2 有参__init__() 方法!

当想要在创建对象时,就设定属性值时,可以使用有参 init() 初始化方法。创建对象时自动触发初始化方法。语法:

class 类名:
	def __init__(self, 参数1, 参数2,...):
		代码s
		...

不需要给self传递参数值;传递参数个数的计算公式为【传递参数个数 = 定义方法后的参数总个数 - 1】

# 1.定义汽车类
class Car:
    def __init__(self,color,number):
        self.color=color
        self.number=number
# 2.创建对象
car=Car("黑色",4)
# 3.获取值
print(f"颜色:{car.color}")
print(f"轮胎个数:{car.number}")

4.3__str__() 方法!

内存地址值,也称为引用。表现形式有两种:
(1)十进制数 5040624,id()函数
(2)十六进制数 0x45AC6

当直接输出对象名时,默认输出的是对象的内存地址值。
__str__(self):输出对象名时,若不想直接输出内存地址值,可重写str()方法。
语法:

class 类名:
	def __str__(self):
		代码
		...
		return 字符串型的结果

说明:必须返回字符串型的结果。

# 1.定义类
class Car:
    def __init__(self,color,number):
        self.color=color
        self.number=number

    def __str__(self):
        return "颜色:"+self.color+",轮胎数:"+str(self.number)
# 2.创建对象
car=Car("黑色",4)
# 3.获取值
print(car)

int类型不能与字符串类型拼接,需要进行转换str(self.number)
return "颜色:"+self.color+",轮胎数:"+self.number TypeError: can only concatenate str (not "int") to str

4.4__del__() 方法

当删除对象时,会自动调用__del__()方法。
__del__(self):当一个对象被删除或销毁时,会被自动调用。

class 类名:
	def __del__(self):
		代码
		...
# 1.定义类
class Car:
    def __init__(self,brand):
        self.brand=brand

    def __del__(self):
        print("=========__del__===========")
        return "颜色:"+self.brand
# 2.创建对象
car=Car("BYD")
# 3.获取值
# del car  
print(car.brand)

运行结果如下:执行结束自动删除释放空间

BYD
=========__del__===========

5 继承基础

5.1 单继承

单继承就是一个子类继承一个父类。语法如下:

class 子类(父类):
	...
# 1.定义父类
class Master(object):
    def __init__(self):
        self.pei_fang="[古老配方]"
    def make_cake(self):
        print("老师傅传授配方")
# 2.定义子类:徒弟单继承
class TuDi(Master):
    pass

ff = TuDi()
print(f"属性:{ff.pei_fang}")
ff.make_cake()

5.1 多继承

多继承就是:一个类同时继承了多个父类。语法如下:

class 类名(父类1,父类2,...):
	代码
	...
# 1.定义父类
class Master(object):
    def __init__(self):
        self.pei_fang="[古老配方]"
    def make_cake(self):
        print("老师傅传授配方")
# 2.学校
class School(object):
    def __init__(self):
        self.pei_fang="[科技狠话新配方]"
    def make_cake(self):
        print("============采用新配方============")
# 3.定义子类:徒弟多继承
class TuDi(Master,School):
    pass

多继承的顺序:
方式1:若要查看顺序问题,则可以使用"类名.mro"属性查看;
方式2:若要查看顺序问题,则可以使用"类名.mro()"方法查看.

# 1.定义父类
class Master(object):
    def __init__(self):
        self.pei_fang="[古老配方]"
    def make_cake(self):
        print("老师傅传授配方")
# 2.学校
class School(object):
    def __init__(self):
        self.pei_fang="[科技狠话新配方]"
    def make_cake(self):
        print("============采用新配方============")

    def programming(self):
        print("=========父类2 的方法")
# 3.定义子类:徒弟多继承
class TuDi(Master,School):
    pass

# 创建对象,调用方法
ff = TuDi()
# 1.先去子类中查找该方法,存在调用
# 2.去第一个父类查找
# 3.去第二个父类查找
print(f"属性:{ff.pei_fang}")
ff.make_cake()
print(f"查看顺序问题:{TuDi.__mro__}")
print(f"查看顺序问题:{TuDi.mro()}")

运行结果如下:

属性:[古老配方]
父类1的方法:老师傅传授配方
查看顺序问题:(<class '__main__.TuDi'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
查看顺序问题:[<class '__main__.TuDi'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>]

1:子类要继承多个父类语法:class 类名(父类1,父类2,...):
2:当子类调用多个父类的同名方法时,要查看顺序问题,可以使用"类名.mro"或"类名.mro()";
3:当某个父类新增了方法后,子类也能继承该方法;
4:当子类继承[多个]父类后,子类可以拥有[多个]父类的属性和方法.

5.3 继承进阶

① 子类重写父类同名方法和属性
方法重写

class Master(object):
    def make_cake(self):
        print("father")
# 方法重写
class TuDi(Master):
    def make_cake(self):
        print("sun")
# 创建对象
tudi=TuDi()
tudi.make_cake()
# 查看执行顺序
print(TuDi.mro())

调用父类同名方法

class School(object):
    def __init__(self,pei_fang):
        self.pei_fang=pei_fang
    def make_cake(self):
        print("father")
class TuDi(School):
    def __init__(self,pei_fang,brand):
        # self.pei_fang=pei_fang  #提示代码的复用性
        super().__init__(pei_fang)
        self.brand=brand
    def make_cake(self):
            # 调用父类的方法
            super().make_cake()
            print("sun")
# 创建对象
tudi=TuDi("配方","品牌")
tudi.make_cake()

5.4 多层继承

多层继承表示有多层父类

# A父类 学校
class School(object):
    def make_cake(self):
        print("fantherA")
# B父类 徒弟
class TuDi(School):
    def make_cake(self):
        print("fantherB")
# B子类 徒孙
class TuSun(TuDi):
    pass

6 面向对象综合案例

案例1:减肥

# 1.定义类
class Student(object):
    def __init__(self,weight):
        self.weight=weight
    def run(self,i):
        for j in range(0,i):
            self.weight-=0.5
        print(f"跑一次减一斤,跑了{i}圈,现在{self.weight}kg")

    def eat(self):
        self.weight+=2
        print(f"大吃大喝一次胖4斤,现在{self.weight}kg")

    def __del__(self):
        print("=========__del__===========")
        return "颜色:"+str(self.weight)
# 2.创建对象
xiaofang=Student(100)
# 3.调用方法
xiaofang.run(5)
xiaofang.eat()

案例1:烤地瓜

# 1.定义类
class Roast(object):
    def __init__(self):
        self.time_count = 0
        self.raw = "生的"
        self.seasoner_list=[]
    # 烧烤
    def bake(self, time):
        self.time_count += time
        # print(f"总共烤了{self.time_count}分钟")
        if self.time_count<15:
            self.raw="还没熟"
            # print("还没熟")
        elif 15 <= self.time_count <= 25:
            # print("烤熟了")
            self.raw = "熟了"
        else:
            self.raw="烤焦了"
            # print("烤焦了")
    # 添加调味料
    def add(self,seasoner):
        self.seasoner_list.append(seasoner)

    # 输出对象名-信息
    def __str__(self):
        # print(len(self.seasoner_list))
        if len(self.seasoner_list)==0:
            print("暂无任何调料~",end="")
        else:
            print("添加的调味料有:",end="")
            for temp in self.seasoner_list:
                print(temp,end=" ")
        print()
        message=f"当前已经烤了{str(self.time_count)}分钟,目前地瓜的生熟状态是{self.raw}"
        return message
# 创建对象
potato = Roast()
# 调用方法,烤10分钟,加调味料
potato.bake(10)
# potato.add("食用油")
print(potato)
# 调用方法,烤20分钟,加调味料
potato.bake(20)
potato.add("孜然粉")
potato.add("食用油")
potato.add("辣椒粉")
print(potato)

7 私有权限

私有属性仅能在本类中访问,不能直接被外部访问
设置私有权限的方式:在方法名前面加上两个下划线 __,格式:def __方法名(self):

# 1.父类
class Master(object):
    def __init__(self):
        self.__money=6000000
# 2.子类
class TuDi(Master):
    pass

ff=TuDi()
print(ff.__money)

私有属性不能被外部访问
在这里插入图片描述
私有属性的获取

class Master(object):
    def __init__(self):
        self.__money=6000000
    # 设置
    def set_money(self,money):
        self.__money=money
    # 获取
    def get_money(self):
        return self.__money
# 创建对象
master=Master()
master.set_money(50000)
print(master.get_money())

8 私有方法

私有方法设定为私有权限后,不会被继承给子类

class Master(object):
    def __make_secret(self):
        print("==========================")
        print("私有方法")
        print("==========================")
    # 简介访问
    def use(self):
        self.__make_secret()
# 创建类
master=Master()
# 调用私用方法
master.use()

9 对象属性和类属性

对象属性

class Phone(object):
    def __init__(self,color,brand):
        self.color=color
        self.brand=brand
    def show(self):
        print(f"访问的车的颜色{self.color}")

phone=Phone("黑色","Audi")
print(f"颜色:{phone.color}")
print(f"品牌:{phone.brand}")

类属性

# 定义类
class People(object):
    count=100
    def show(self):
        print("森林防火,人人有责")
# 调用使用
print(People.count)

10 类方法和静态方法

类方法
语法:

@classmethod  #装饰器
def 类方法名(cls):
...

调用:
类名.类方法名() # 推荐使用对象名.类方法名()

class Dog(object):
    # a类方法
    @classmethod
    def eat(cls):
        print("类方法")
# 调用
Dog.eat()

dog=Dog()
dog.eat()
class Cat(object):
    __tooch=10
    # a类方法
    @classmethod
    def get_tooch(cls):
        # return Dog.__tooch
        return cls.__tooch
# 调用
print(Dog.get_tooch())

静态方法
静态方法需要通过装饰器@staticmethod来来标识其为静态方法,且静态方法不需要多定义参数,格式
如下:

@staticmethod
def 静态方法名():
...

调用:类名.静态方法名 # 推荐使用
对象名.静态方法

class Game(object):
    # 定义静态方法,括号无参数
    @staticmethod
    def show_menu():
        print("==================")
        print("\t1.开始游戏")
        print("\t2.暂停游戏")
        print("\t3.结束游戏")
        print("==================")
# 调用使用
Game.show_menu()

第八章 网络编程

三要素:IP地址、端口、协议。
IP地址:就是标识网络中设备的一个地址
端口:作用是找到计算机中的应用软件.

知名端口号:是指众所周知的端口号,范围从0到1023。 http:80 https:443 75
动态端口号:一般程序员开发应用程序使用端口号称为动态端口号, 范围是从1024到65535。

协议:作用是定义通信规则,并确定传输数据类型为bytes。
TCP协议:(Transmission Control Protocol)简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP的特点:

①面向连接:通信双方必须先建立好连接才能进行数据传输,数据传输完成后,需要断开连接,以释放系统资源。
②可靠传输:都建立了连接,传输数据可靠、稳定
必须要先建立连接,相对效率较低;
大多数服务器程序都是使用TCP协议开发的。

1 socket套接字与TCP开发流程

只要跟网络相关的应用程序或者软件都使用到了socket 。
Python中有专门的socket类用来处理用户的请求和响应,利用socket类可以轻松实现两台计算机间的通信。

# 1.导入模块
import socket
# 2.创建socket对象
tcp_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #TCP协议
# 3.输出内容
print(tcp_sock)

常用于服务器端的函数如下:
bind(address):绑定地址(host,port)到socket套接字,在AF_INET下,address以元组(host,port)的形式表示地址。其中,参数host表示字符串类型的主机名或IP地址;port表示int类型的端口号【1024-65535】。
listen(backlog):开始TCP监听。参数backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了,最大值可设置为128。
accept():被动接受TCP客户端连接,等待连接的到来,返回一个connection对象,以元组形式显示,且元组的第一个参数为已建立连接的socket对象,第二个参数为客户端地址address。

能同时应用于服务器端和客户端的函数如下:
recv(bufsize):用于接收TCP数据,数据以bytes二进制形式返回,bufsize指定要接收的最大数据量,可设置为1024的倍数。 4096=4*1024
send(data):发送TCP数据,将data中的数据发送到连接的套接字,data为bytes二进制数据。 bytes类型转换字符串。
close():关闭套接字。
setsockopt(level,optname,value):可设置端口号复用,让程序退出端口号并立即释放。level可指定为SOL_SOCKET, optname可指定为SO_REUSEADDR, value可指定为True。 了解

2 字符串str与二进制bytes类型转换

encode(encoding):用于把字符串编码转换为二进制数据,其中,encoding表示编码格式,常设置为 utf-8 。
decode(encoding):用于把二进制数据解码转换为字符串,其中,encoding表示编码格式,常设置为 utf-8 。

# ----------------------------12 字符串转换为二进制-----------------------
str="转换二进制"
# 转换二进制
result=str.encode("utf-8")
print(result)
# ----------------------------13 二进制转换为字符串-----------------------
# 二进制
bs=b"python"
# print(type(bs))
# 2.转换为字符串
result1=bs.decode("utf-8")
print(result1)

3 TCP编程

TCP服务器端操作步骤流程:

  1. 创建服务端套接字对象;socket()
  2. 绑定端口号;bind()
  3. 设置监听;listen()
  4. 等待接受客户端的连接请求;【被动连接】accept()
  5. 发送数据;send()
  6. 接收数据;recv()
  7. 关闭套接字。close()

服务器端server:创建一个socket对象服务器端,并向客户端发送消息内容

# 1.导入模块
import socket
# 2.创建socket对象
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #常量,大写,单词之间用下划线
# 3.绑定地址
host="127.0.0.1"
port=8000
address=(host,port)
server_socket.bind(address)
# 4.设置监听
server_socket.listen(5)
print(f"服务器正在端口号为{port}进行监听...")
# 5.被动连接[元组结果(被动socket,客户端地址)]
acc_sock,client_addr=server_socket.accept()
print(f"已成功连接,客户端地址为:{client_addr}")
# 6.发送消息
message="hello,Socket".encode("utf-8")
acc_sock.send()
server_socket.close()
print("===================服务客户端已结束")

TCP客户端操作步骤流程:

  1. 创建客户端套接字对象;socket()
  2. 客户端连接服务器端;connect()
  3. 接收数据;recv()
  4. 发送数据;send()
  5. 关闭套接字。close()

客户端:用来接收服务器端发送过来的内容。 receiver recv()

# 1.导入模块
import socket
# 2.创建socket对象
client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 3.连接服务器
host="127.0.0.1"
port=8000
address=(host,port)
client_socket.connect(address)
# 4.接收消息
data=client_socket.recv(1024)
msg=data.decode("utf-8")
# 5.关闭
client_socket.close()
print("=======已经成功接受消息内容!!!")
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值