python面向对象(1)

简介: python面向对象(1)

知识点小结

该处仅用于快速复习,详细知识及代码如何编写点请跳过。


Python中支持两种编程方式来写代码,分别是:函数式编程、面向对象式编程。


声明一个类:class Ok: 或class Ok() 或 class Ok(object) ,py3默认继承object,新式类,py2,经典类。


1.根据类型创建一个对象,内存的一块区域 。

2.执行__init__方法,模块会将创建的那块区域的内存地址当self参数传递进去。


self是什么?


self是一个参数,在通过 对象.方法 的方式去执行方法时,这个参数会被python自动传递(值为调用当前方法的对象)


即使第一个参数不写self,如改写成qqqq,此时qqqq即为self。


什么是对象?


对象,基于类实例化出来”一块内存“,默认里面没有数据;经过类的 __init__方法,可以在内存中初始化一些数据。


什么时候用面向对象编程好一些?


仅做数据封装。


封装数据 + 方法再对数据进行加工处理。


创建同一类的数据且同类数据可以具有相同的功能(方法)。


三大特性:封装 继承 多态


- 封装,将方法封装到类中 或 将数据封装到对象中,便于以后使用。

- 继承,将类中的公共的方法提取到基类中去实现。

- 多态,Python默认支持多态(这种方式称之为鸭子类型),最简单的基础下面的这段代码即可。

   def func(arg):

       v1 = arg.copy() # 浅拷贝 即要能执行这种方法,不然会报错。

       print(v1)

成员: 实例变量 类变量,绑定方法 类方法 静态方法,属性。

class Ok:
    country = 'china'
    def __init__(self,name):
        self.name = name
    def fuc1(self):
        print('这是绑定方法')
    @classmethod
    def fuc2(cls):
        print('这是类方法')
    @staticmethod
    def fuc3():
        print('这是静态方法')
    @property
    def fuc4(self):
        print('这是属性')

分清楚每一步修改或者增加的是那里的对象

class People:
    country = 'china'
    def __init__(self, name='未输入', age=18):
        self.name = name
        self.age = age
    def fuc1(self):
        print(self.name, self.age)
person1 = People('卢本伟', 18)
print(person1.country)  # china 对象中没有 会向类变量中寻找 
person1.name = 'lbw' #将对象中的name变量修改
person1.country = '中国' #对象中没有country 会创建一个country对其进行赋值
print(person1.name, person1.age, person1.country, People.country) #lbw 18 中国 china
class People:
    country = 'china'
    def __init__(self, name='未输入', age=18):
        self.name = name
        self.age = age
    def fuc1(self):
        print(self.name, self.age, self.country)
class Ok(People):
    name = 'nihao'
    def fuc2(self):
        print(self.name, self.age, self.country)
    @classmethod
    def fuc3(cls):
        print(cls.name)
person = Ok('周润发', 19)  # 相当于自己的类在有一个init
person.fuc1()  # 周润发 19 china self是自己的优先在Ok里找
person.fuc2()  # 周润发 19 china
person.fuc3()  # 你好
Ok.country = '韩国' #添加类变量 优先找实例变量->自己的类变量->父类类变量
Ok.name = '不知道'
person.fuc1()  # 周润发 19 韩国
person.fuc2()  # 周润发 19 韩国
person.name = '卢本伟'
person.country = '日本'  # 对象中添加了实例变量country
print(People.country, Ok.country)  # china 韩国
person.fuc1()  # 卢本伟 19 日本 
person.fuc2()  # 卢本伟 19 日本

编写属性的方式有哪些?

(点击目录 属性 跳转)

成员修饰符(公有/私有)

对于私有成员,在成员名字前加两道下划线__,即为私有。

class Ok:
    def __init__(self, name='未输入', age=18):
        self.__name = name
        self.age = age
    def __fuc1(self):
        pass
    def fuc2(self):
        self.__name = 'lbw'
        print(self.__name)
class Yes(Ok):
    def fuc3(self):
        print(self.__name) #这样不执行不会报错
k = Ok('周润发')
k.fuc2() #lbw
print(k.age) #18
kk = Yes()
kk.fuc3() #在这里会报错  子类也无法调用父类的自私有变量/方法

注意:要看self写在哪个类里

class Base(object):
    def __data(self):
        print("base.__data")
    def num(self):
        print("base.num")
        self.__data()
class Foo(Base):
    def func(self):
        self.num()
obj = Foo()
obj.func()
'''
base.num
base.__data
虽然self一直都是Foo实例化的对象的,但其在调用__data时,是在Base类内部调用的
'''

写在最后,按理说私有成员是无法被外部调用,但如果用一些特殊的语法也可以(Flask源码中有这种写法,大家写代码不推荐这样写)。

class Foo(object):
    def __init__(self):
        self.__num = 123
        self.age = 19
    def __msg(self):
        print(1234)
obj = Foo()
print(obj.age)
print(obj._Foo__num)
obj._Foo__msg()

特殊成员

new init call str dict add      getitem setitem delitem      enter exit    iter  

要明白每个的作用  去目录跳转查看 迭代器 生成器 可迭代对象 等的内容

class IT(object):
    def __init__(self):
        self.counter = 0
    def __iter__(self):
        return self
    def __next__(self):
        self.counter += 1
        if self.counter == 3:
            raise StopIteration()
        return self.counter
class Foo(object):
    def __iter__(self):
        return IT()
obj = Foo() # 可迭代对象
for item in obj: # 循环可迭代对象时,内部先执行obj.__iter__并获取迭代器对象;不断地执行迭代器对象的next方法。
    print(item)

mro和c3算法

继承关系 :从左到右,深度优先,大小钻石,留住顶端

内置函数补充:classmethod、staticmethod、property、callable、super 、type 、isinstance 、issubclass

异常处理写法和细分

面向对象基础

目标:了解面向对象并可以根据面向对象知识进行编写代码。

概要:

  • 初识面向对象
  • 三大特性(面向对象)
  • 封装
  • 继承
  • 多态
  • 再看数据类型

1. 初识面向对象

想要通过面向对象去实现某个或某些功能时需要2步:

  • 定义类,在类中定义方法,在方法中去实现具体的功能。
  • 实例化类并的个一个对象,通过对象去调用并执行方法。
class Message:
    def send_email(self, email, content):
        data = "给{}发邮件,内容是:{}".format(email,content)
        print(data)
msg_object = Message() # 实例化一个对象 msg_object,创建了一个一块区域。
msg_object.send_email("xxxx@live.com","注册成功")

注意:1.类名称首字母大写&驼峰式命名;2.py3之后默认类都继承object;3.在类种编写的函数称为方法;4.每个方法的第一个参数是self。

类中可以定义多个方法,例如:

class Message:
    def send_email(self, email, content):
        data = "给{}发邮件,内容是:{}".format(email, content)
        print(data)
    def send_wechat(self, vid, content):
        data = "给{}发微信,内容是:{}".format(vid, content)
        print(data)
msg_object = Message()
msg_object.send_email("xxxxx@live.com", "注册成功")
msg_object.send_wechat("lbw", "注册成功")

你会发现,用面向对象编程写的类有点像归类的意思:将某些相似的函数划分到一个类中。

但,这种编写方式让人感觉有些鸡肋,直接用 函数 写多好呀。对吧?

别着急,记者往下看。

1.1 对象和self

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

class Message:
    def __init__(self, content):
        self.data = content
    def send_email(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_object = Message("注册成功")
msg_object.send_email("xxxxx@live.com") # 给xxxxx@live.com发邮件,内容是:注册成功
msg_object.send_wechat("lbw") # 给lbw发微信,内容是:注册成功

通过上述的示例,你会发现:


对象,让我们可以在它的内部先封装一部分数据,以后想要使用时,再去里面获取。


self,类中的方法需要由这个类的对象来触发并执行( 对象.方法名 ),且在执行时会自动将对象当做参数传递给self,以供方法中获取对象中已封装的值。


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


当然,根据类也可以创建多个对象并执行其中的方法,例如:

class Message:
    def __init__(self, content):
        self.data = content
    def send_email(self, email):
        data = "给{}发邮件,内容是:{}".format(email, self.data)
        print(data)
    def send_wechat(self, vid):
        data = "给{}发微信,内容是:{}".format(vid, self.data)
        print(data)
msg_object = Message("注册成功")
msg_object.send_email("lbw@live.com") # 给lbw@live.com发邮件,内容是:注册成功
msg_object.send_wechat("xxx")
login_object = Message("登录成功")
login_object.send_email("lbw@live.com") # 给lbw@live.com发邮件,内容是:登录成功
login_object.send_wechat("xxx")

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


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


self,本质上就是一个参数。这个参数是Python内部会提供,其实本质上就是调用当前方法的那个对象。


对象,基于类实例化出来”一块内存“,默认里面没有数据;经过类的 __init__方法,可以在内存中初始化一些数据。

1.2 常见成员

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

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

注意:还有很多其他的成员,后续再来介绍。

class Person:
    def __init__(self, n1, n2):
        # 实例变量
        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("lbw",20)
p1.show()
# 或
# p1 = Person("lbw",20)
# Person.show(p1)
# 初始化,实例化了Person类的对象叫p1
p1 = Person("lbw",20)

1.3 应用示例

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

class UserInfo:
    def __init__(self, name, pwd,age):
        self.name = name
        self.password = pwd
        self.age = age
def run():
    user_object_list = []
    # 用户注册
    while True:
        user = input("用户名:")
        if user.upper() == "Q":
            break
        pwd = input("密码")
        # user_object对象中有:name/password
        user_object = UserInfo(user, pwd,19)
        # user_dict = {"name":user,"password":pwd}
        user_object_list.append(user_object)
     # user_object_list.append(user_dict)
    # 展示用户信息
    for obj in user_object_list:
        print(obj.name, obj.password)
总结:
  - 数据封装到对象,以后再去获取。
    - 规范数据(约束)
  1. 注意:用字典也可以实现做封装,只不过字典在操作值时还需要自己写key,面向对象只需要 . 即可获取对象中封装的数据。
  2. 将数据分装到对象中,在方法中对原始数据进行加工处理。
user_list = ["用户-{}".format(i) for i in range(1,3000)]
# 分页显示,每页显示10条
while True:
    page = int(input("请输入页码:"))
    start_index = (page - 1) * 10
    end_index = page * 10
    page_data_list = user_list[start_index:end_index]
    for item in page_data_list:
        print(item)
class Pagination:
    def __init__(self, current_page, per_page_num=10):
        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, 3000)]
# 分页显示,每页显示10条
while True:
    page = input("请输入页码:")
    # page,当前访问的页码
    # 10,每页显示10条数据
  # 内部执行Pagination类的init方法。
    pg_object = Pagination(page, 20)
    page_data_list = user_list[ pg_object.start() : pg_object.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 f:
            f.write(res.content)
            f.flush()
    def multi_download(self, video_list):
        for item in video_list:
            self.download(item[0], item[1])
if __name__ == '__main__':
    douyin_object = DouYin("videos")
    douyin_object.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_object.multi_download(video_list)

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

class Police:
    """警察"""
    def __init__(self, name, role):
        self.name = name
        self.role = role
        if role == "队员":
            self.hit_points = 200
        else:
            self.hit_points = 500
    def show_status(self):
        """ 查看警察状态 """
        message = "警察{}的生命值为:{}".format(self.name, self.hit_points)
        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_object):
        """ 开枪射击某个警察 """
        police_object.hit_points -= 5
        police_object.show_status()
        self.blood -= 2
    def strafe(self, police_object_list):
        """ 扫射某些警察 """
        for police_object in police_object_list:
            police_object.hit_points -= 8
            police_object.show_status()
    def show_status(self):
        """ 查看恐怖分子状态 """
        message = "恐怖分子{}的血量值为:{}".format(self.name, self.blood)
        print(message)
def run():
    # 1.创建3个警察
    p1 = Police("lbw", "队员")
    p2 = Police("uzi", "队员")
    p3 = Police("mlxg", "队长")
    # 2.创建2个匪徒
    t1 = Terrorist("alex")
    t2 = Terrorist("eric")
    # alex匪徒射击mlxg警察
    t1.shoot(p3)
    # alex扫射
    t1.strafe([p1, p2, p3])
    # eric射击uzi
    t2.shoot(p2)
    # lbw炸了那群匪徒王八蛋
    p1.bomb([t1, t2])
    # lbw又炸了一次alex
    p1.bomb([t1])
if __name__ == '__main__':
    run()

总结:

  • 仅做数据封装。
  • 封装数据 + 方法再对数据进行加工处理。
  • 创建同一类的数据且同类数据可以具有相同的功能(方法)。
相关文章
|
Java 程序员 C++
Python 面向对象详解!
本文详细介绍了Python中的面向对象编程(OOP),包括类、对象、继承、封装、多态和抽象等核心概念。通过具体示例,解释了如何使用类定义对象的属性和方法,以及如何通过继承实现代码重用。文章还探讨了封装和多态的重要性,并介绍了私有属性和抽象类的使用方法。最后,总结了OOP的四大支柱:封装、抽象、继承和多态,强调了这些概念在Python编程中的应用。适合Java程序员扩展Python编程知识。
346 2
|
9月前
|
Python
Python 高级编程与实战:深入理解面向对象与并发编程
本文深入探讨Python的高级特性,涵盖面向对象编程(继承、多态、特殊方法、类与实例属性)、异常处理(try-except、finally)和并发编程(多线程、多进程、异步编程)。通过实战项目如聊天服务器和异步文件下载器,帮助读者掌握这些技术,编写更复杂高效的Python程序。
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
166 0
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
243 1
|
人工智能 自然语言处理 开发者
Python基础教程——面向对象
Python基础教程——面向对象
|
Python
Python面向对象(2)
【10月更文挑战第14天】
164 6
Python面向对象(2)
|
12月前
|
关系型数据库 开发者 Python
Python编程中的面向对象设计原则####
在本文中,我们将探讨Python编程中的面向对象设计原则。面向对象编程(OOP)是一种通过使用“对象”和“类”的概念来组织代码的方法。我们将介绍SOLID原则,包括单一职责原则、开放/封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则有助于提高代码的可读性、可维护性和可扩展性。 ####
|
设计模式 程序员 C语言
Python面向对象
【10月更文挑战第13天】
131 2
Python面向对象
|
前端开发 Python
Python编程的面向对象有哪些(二)
Python编程的面向对象(二)—类的多态
119 7

推荐镜像

更多