python初识面向对象

python初识面向对象

  • python支持两种编程方式:面向对象、函数式编程

    • 函数式
    # 定义函数,在函数中实现功能
    def func():
        print("函数式编程")
    
    # 执行函数
    func()
    
    • 面向对象
    # 定义一个类
    class Foo(object):
        # 类中定义方法
        def func(self):
            print("面向对象编程")
    
    
    # 实例化类的对象
    obj = Foo()
    # 执行类的方法
    obj.func()
    

1.初识面向对象

面向对象实现功能步骤:

  • 定义类:在类中定义方法,在方法中实现具体的功能。
  • 实例化类的对象,通过对象调用并执行方法。
class Message(object):
    def send_email(self, email, content):
        data = "给{}发邮件,内容是{}".format(email, content)
        return data


# 实例化类的对象,创建一块区域
msg_object = Message()
msg_object.send_email("18888888888@163.com", "达莱,你好")

注意:

  • 类名首字母大写&驼峰式命名
  • python3之后默认的类都继承object
  • 在类中编写的函数称为方法
  • 每个方法的第一个参数都是self。

类中可以定义多个方法:

class Message(object):

    def send_message(self, email, content):
        data = "给{}发邮件,内容是:{}".format(email, content)
        print(data)

    def send_wechat(self, vid, content):
        data = "给{}发微信,内容是:{}".format(vid, content)
        print(data)


# 示例化类的对象
msg_obj = Message()
# 执行类中的2个方法
msg_obj.send_message("18888888888@163.com", "你好")
msg_obj.send_wechat("查苏娜", "hello")

1.1对象和self

在每个类中都可以定义一个特殊的::__init__ 初始化方法,在实例化类创建对象时自动执行,即:对象=类()

class Message(object):

    def __init__(self, content):
        self.data = content

    def send_message(self, email):
        data = "给{}发邮件,内容是:{}".format(email, self.data)
        print(data)

    def send_wechat(self, vid):
        data = "给{}发微信,内容是:{}".format(vid, self.data)
        print(data)


# 对象 = 类名() # 自动执行类中的 __init__ 方法。

# 1. 根据类型创建一个对象,内存的一块 区域 。
# 2. 执行__init__方法,模块会将创建的那块区域的内存地址当self参数传递进去。    往区域中(data="注册成功")
# 示例化类的对象
msg_obj = Message("注册成功")
# 给18888888888@163.com发邮件,内容是:你好
msg_obj.send_message("18888888888@163.com", "你好")  
# 给查苏娜发邮件,内容是:hello
msg_obj.send_wechat("查苏娜", "hello")
  • 对象:可以在他内部先封装一部分数据,以后想用时,再去里边获取
  • self,类中的方法需要由这个类的对象来触发并执行(对象.方法名),且在执行时会自动将对象当做采纳数传递给self,以供方法中获取对象中已封装的值。

注意:除self默认值参数以外,方法中的参数的定义和执行与函数是相同的。

根据类创建读个对象,并执行其中的方法,如下:

class Message:

    def __init__(self, context):
        self.data = context

    def send_email(self, email):
        data = "给{}发邮件,内容是:{}".format(email, self.data)
        print(data)

    def send_chat(self, chat):
        data = "给{}发微信,内容是:{}".format(chat, self.data)
        print(data)


msg_obj = Message("注册成功!")
msg_obj.send_email("查苏娜")  # 给查苏娜发邮件,内容是:注册成功!
msg_obj.send_chat("达莱")  # 给达莱发微信,内容是:注册成功!

面向对象的思想:将一些数据封装到对象中,在执行方法中,再去对象中获取

函数式思想:函数内部需要的数据均通过参数形式传递。

  • self,本质是一个参数,这个参数是python内部会提供,其实本质上就是调用当前方法的那个对象。
  • 对象,基于类实例化出来的“一块内存”,默认里边没有参数;经过类的 __init__方法,可以在内存中初始化一些数据

1.2 常见成员

编写面向对象代码时,常见成员有:

  • 实例变量:属于对象,只能通过对象调用
  • 绑定方法,属于类,通过对象调用或通过类调用。

注意:还有许多成员变量。

class Person:

    def __init__(self, country, n1, n2):
        # 实例变量
        self.country = country
        self.name = n1
        self.age = n2

    def show(self):
        msg = "我叫{},今年{}岁。".format(self.name, self.age)
        print(msg)

    def all_message(self):
        msg = "我是{}人,我叫{},今年{}岁。".format(Person.country, self.name, self.age)
        print(msg)

    def total_message(self):
        msg = "我是{}人,我叫{},今年{}岁。".format(self.country, self.name, self.age)
        print(msg)
# 执行绑定方法
p1 = Person("查苏娜",20)
p1.show()
# 或
# p1 = Person("达莱",20)
# Person.show(p1)


# 初始化,实例化了Person类的对象叫p1
p1 = Person("达莱",20)

1.3应用示例

1.将数据封装到一个对象,便于以后使用。

class User:
    def __init__(self, name, pwd, age):
        self.name = name
        self.pwd = pwd
        self.age = age

    def run(self):
        user_object_list = []
        # 用户注册
        while True:
            user = input("用户名:")
            if user.upper() == "Q":
                break
            pwd = input("密码:")
            
            # user_object对象中有:name/password
            user_obj = User(user, pwd, 21)
            # user_dict = {"name": user, "password": pwd}
            user_object_list.append(user_obj)
            # user_object_list.append(user_dict)
			
            
            # 展示用户信息
            for obj in user_object_list:
                print(obj.name, obj.pwd)


obj = User("zz", "add", 21)
obj.run()

总结:

  • 数据封装到对象,以后再去获取。
  • 规范数据(约束)

注意:用字典也可以实现做封装,只不过字典在操作值时还需要自己写key,面向对象只需要 . 即可获取对象中封装的数据。

2.将数据封装到对象中,在方法中对原始数据进行加工处理。

class Pagination:
    def __init__(self, current_page, per_page_num=10):
        self.per_page_num = per_page_num
        self.current_page = current_page
        self.per_page_num = per_page_num

        if not current_page.isdecimal():
            self.current_page = 1
            return
        current_page = int(current_page)
        if current_page < 1:
            self.current_page = 1
            return
        self.current_page = current_page

    def start(self):
        return (self.current_page - 1) * self.per_page_num

    def end(self):
        return self.current_page * self.per_page_num


user_list = ["用户-{}".format(i) for i in range(1, 30000)]

# 分页显示,每页显示10条


while True:
    page = input("请输入页码:")

    pg_obj = Pagination(page, 20)
    page_data_list = user_list[pg_obj.start(): pg_obj.end()]

    for item in page_data_list:
        print(item)

将数据封装到一个对象中,然后再方法中对已封装的数据进行操作。

import os
import requests


class DouYin:
    def __init__(self, folder_path):
        self.folder_path = folder_path

        if not os.path.exists(folder_path):
            os.makedirs(folder_path)

    def download(self, file_name, url):
        res = requests.get(
            url=url,
            headers={
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
                              "AppleWebKit/537.36 (KHTML, like Gecko) "
                              "Chrome/87.0.4280.88 Safari/537.36 FS"
            }
        )

        file_path = os.path.join(self.folder_path, file_name)
        with open(file_path, mode="wb") as file_object:
            file_object.write(res.content)
            file_object.flush()

    def multi_download(self, video_list):
        for item in video_list:
            self.download(item[0], item[1])


if __name__ == "__main__":
    douyin_obj = DouYin("vodeos")

    douyin_obj.download(
        "罗斯.mp4",
        "https://aweme.snssdk.com/aweme/v1/playwm/"
        "?video_id=v0200f240000buuer5aa4tij4gv6ajqg"

    )
    video_list = [
        ("a1.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300fc20000bvi413nedtlt5abaa8tg"),
        ("a2.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fb60000bvi0ba63vni5gqts0uag"),
        ("a3.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg")
    ]

douyin_obj.multi_download(video_list)

3.根据类创建多个对象,在方法中对对象中的数据进行修改。

class Police:

    # 警察类
    def __init__(self, name, role):
        self.name = name
        self.role = role
        if role == "队员":
            self.life_value = 200
        else:
            self.life_value = 300

    def show_status(self):
        # 查看警察状态
        message = "警察{}生命值为{}".format(self.name, self.life_value)
        print(message)

    def bomb(self, terrorist_list):
        # 投炸弹,炸恐怖分子
        for terrorist in terrorist_list:
            terrorist.blood -= 200
            terrorist.show_status()


class Terrorist:
    # 恐怖分子
    def __init__(self, name, blood=300):
        self.name = name
        self.blood = blood

    def shoot(self, police_obj):
        # 开枪射击警察
        police_obj.life_value -= 5
        police_obj.show_status()
        self.blood -= 2

    def strafe(self, police_obj_list):
        # 扫射某些警察
        for police_obj in police_obj_list:
            police_obj.life_value -= 8
            police_obj.show_status()

    def show_status(self):
        # 查看恐怖分子状态
        message = "恐怖分子{}的血量为:{}".format(self.name, self.blood)
        print(message)


def run():
    # 创3个警察
    p1 = Police("查苏娜", "队长")
    p2 = Police("达莱", "队员")
    p3 = Police("芽麦", "队员")

    # 3个匪徒
    t1 = Terrorist("莱恩")
    t2 = Terrorist("科尔")

    # 莱恩射击警察芽麦
    t1.shoot(p3)
    # 莱恩扫射查苏娜、达莱,芽麦
    t1.strafe([p1, p2, p3])
    # 莱恩射击达莱
    t2.shoot(p2)
    # 查苏娜炸莱恩和科尔
    p1.bomb([t1, t2])
    # 查苏娜又炸莱恩
    p1.bomb([t1])


if __name__ == '__main__':
    run()

总结:

  • 仅做数据封装
  • 封装数据 + 方法在对数据进行加工处理
  • 创建同一类的数据且同类数据可以具有相同的功能(方法)。

2.三大特性

面向对象编程在很多语言中都存在,这种编程方式有三大特性:封装、继承、多态。

2.1封装

封装主要体现在两个方面:

  • 将同一类方法封装到一个类中
  • 将数据封装到了对象中,在实例化一个对象时,可以通过____init____初始化方法在对象中封装一些数据,便于以后使用。

2.2 继承

传统的理念中有:儿子可以继承父亲的财产。

在面向对象中也有这样的理念,即:子类可以继承父类中的方法和类变量(不是拷贝一份,父类的还是属于父类,子类可以继承而已)。

父类
子类

基类
派生类
class Base:

    def func(self):
        print("Base.func")

class Son(Base):
    
    def show(self):
        print("Son.show")
        
s1 = Son()
s1.show()
s1.func() # 优先在自己的类中找,自己没有才去父类。

s2 = Base()
s2.func()
class Base:
    def f1(self):
        pass

class Foo(Base):

    def f2(self):
        pass
    
class Bar(Base):
    
    def f3(self):
        pass
    
o1 = Foo()
o1.f2()
o1.f1()
  • 执行对象方法时,优先去当前对象所关联的类中找,没有的话才去它的父类中查找
  • Python支持多继承:先继承左边、再继承右边的
  • self到底是谁?去self对应的那个类中去获取成员,没有就按照继承关系向上查找

2.3多态

多态,多种形态。

  • 其他编程语言多态
  • Python中多态

在Python中,由于Python对数据类型没有任何限制,所以他天生支持多态。

class Email(object):
    def send(self):
        print("发邮件")

        
class Message(object):
    def send(self):
        print("发短信")
        
        
        
def func(arg):
    v1 = arg.send()
    print(v1)
    

v1 = Email()
func(v1)

v2 = Message()
func(v2)

在程序设计中,鸭子类型(duck typing)是动态类型的一种风格。在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型,例如:一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。

小结:

  • 封装,将方法封装到类中 或 将数据封装到对象中,便于以后使用。
  • 继承,将类中的公共的方法提取到基类中去实现。
  • 多态,Python默认支持多态(这种方式称之为鸭子类型),最简单的基础下面的这段代码即可。
def func(arg):
    v1 = arg.copy() # 浅拷贝
    print(v1)
    
# func("达莱")
func([11,22,33,44])

3.扩展:数据类型

str、list、dict等数据类型,其实都一个类,根据类可以创建不同类的对象。

# 实例化一个str类的对象v1
v1 = str("达莱") 

# 通过对象执行str类中的upper方法。
data = v1.upper()

print(data)

总结:

1.类和对象的关系

2.面向对象编程中常见的成员:

  • 绑定方法
  • 实例变量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值