掉进悬崖的小白,总结python基础第一阶段,面向对象复习题刷起来!

深入讲解Python面向对象编程,涵盖函数、类定义、封装、继承、多态等核心概念,详解类与对象的关系,以及如何在Python中实现封装、继承和多态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

掉进悬崖的小白,总结python基础第一阶段,面向对象复习题刷起来!

1.函数相关

函数的含义

广义:
为获得某种东西或达到某种目的而采取的手段与行为方式。
狭义:
函数是指由一系列的程序语句组成的代码块
特性:
1.带名字的代码段
2.函数是代码重复使用的重要手段,是重用的基本手段:
无论现实世界还是程序世界,都以函数来达到重用的目的

函数的定义

定义语法:[]表示可选 <>表示必备
<函数名>([参数列表])<:>
待执行语句
如果有需要显式返回<return 标识符>或

函数的参数

形式参数:由函数编写者在预定义时限定
实际参数:任意的数据类型(为形参赋值)在函数的调用者中定义赋值

函数的调用过程

1.调用者和被调用者相互可见,采用直接调用的方式 函数名()
2.调用者和被调用者相互不可见,先import模块再调用:注意调用时带上模块.
3.特殊的调用方式,(调用类方法(类名.),调用成员方法(对象.))
析构函数等魔法函数需要用特殊的方案调用(在类内使用CTRL+o选择调用,或者自己打def._ _ xxx_ _)

函数的返回值

返回值类型:
所有函数都需要返回
只是没写return的会自动返回None
函数有无返回值取决于函数的调用者是否需要返回值
注意:
函数遇到return立即退出并返回 so也常作为控制方法结束的手段

函数的传参规则

参数传递需要明白的要点:
形参的修正对实参的影响程度

参数传递的方式:
形式参数 = 实际参数

传参规则:
根据形式参数类型的不同 对实际参数的影响程度也不相同
A:不可变类型:字符串、数字、布尔、元组
B:列表、类、对象、集合、字典

函数内部形参修正对函数外实参的影响程度:
A:不可变类型 不影响实际参数
B:影响实际参数(如列表,函数内部不修改整个列表时,不影响实参列表,只是修改了列表的内部)

2.注释的使用

#、单行注释
“”“、”“”、多行注释(_ doc _ 访问注释)
‘’‘ ’‘’多行注释(不推荐)

3.访问控制的种类及其作用范围

完全公开: 标识符不以_开始
保护(单下划线前缀) :_标识符
私有(双下划线前缀) :__标识符
完全公开:任意位置均可访问
保护:当前类及子类可访问
私有:只能在当前类内访问

4.什么是面向对象

面向对象编程(Object Oriented Programming)简称OOP:
用认识一个系统的方式来分析、设计和实现一个系统
面试答案:封装、继承和多态即为面向对象

5.如何抽象出类 怎么抽象

想象这个事物有什么(属性),能做什么(方法)
要求:
数据抽象(变量)—描述某类对象的状态(对象相互区别的物理量);
代码抽象(函数)—描述某类对象的共有的功能。

如何实现抽象:
1.分析事物,提取其状态(变量)和行为(函数);
2.要有主次:关注重要的,忽略不重要的

6.类怎么定义

类(class):一种复杂的自定义数据类型
类之重要:面向对象的核心
类的定义语法:
class <类名>(父类列表):
构造方法 (制造对象模板,开辟对象地址空间)
类变量…(类内共用,可以在未创建类的对象前就用类名直接调用类属性)
初始化方法(self,对象的变量…)(对象实例化)
类方法(1.在未产生对象的情况下即可使用类名访问 2.对类变量进行内部封装处理)
静态方法(和类和对象都无关,只是一个功能,用来表达层级关系)
属性
成员方法/对象方法
析构方法
(垃圾回收)
7.类内部都有什么内容 各有什么作用

8.怎么使用类内部定义的内容 请详细点说明

使用类的方式:和一般类型一致(声明->赋值->使用)
如何声明:
对象引用 = 类名(构造中需要的实参)
使用:
通过对象引用来寻找对象的变量和方法
对象引用.对象的变量
对象引用.对象方法([参数列表])
对象的构造过程
1.为对象开辟空间,使用__new__魔术方法;
2.调用初始化方法__init__初始化;
3.返回对象的引用。

类和对象的关系:
1.类是对象的模板
2.一个类可以创建多个对象
3.对象是类一个特定的个体
4.对象有独立的内存空间,不会互相影响

9.self的作用

self :
对象方法中必备的第一个参数
声明:初始化及每个对象方法必须写,且必须为第一参数
作用:
1.初始化或对象方法被调用时,立即自动指向调用该方法的对象,无需显式传参(代表当前对象
2.区分同名的局部变量和对象变量

10.封装的含义

将字段(数据成员)和行为(代码成员)相组合的一种机制。
目的:
1.控制对象状态的范围
2.加强对象自身的内联(联动)性
3.便于外部使用

11.怎么实现封装

封装的基本要求:
特定边界:所有的内部变化都限制在此边界内(类内部);
特定访问权限:在对象外部不能访问或修改受保护的内部实现细节(_ _成员)
有外部接口(set/get方法):此对象利用它与其它对象发生关联

使用属性装饰器来完成封装:

主要用于快速构建代码:
prop+回车:生成只读属性
props+回车:生成可读写属性
propsd+回车:生成可读写删属性

12.继承的含义

继承是由已有的类创建新类的机制。
由继承得到的类称为子类(派生类)
被继承的类称为父类(超类)(基类)
继承的作用:
实现软件可重用的重要方式
增强软件可扩充性
提高软件的可维护性

13.派生类(子类)继承到了父类的什么内容?

可继承的内容:
子类继承父类私有以外的成员变量
:需要super().init(父级初始化参数)或使用父级统一的初始化方法
子类继承父类私有以外的成员方法
子类继承父类的析构方法
子类不能删除父类的成员
子类可以覆盖/重写父类成员方法
子类可以增加自己独有的成员
子类对象对父类成员的访问权限:
子类可以访问父类私有成员(__XXX)以外的内容

14.怎么实现封装

同11题
封装时注意避免深度递归
函数直接或间接调用函数本身,则该函数称为递归函数

class Person:
    def __init__(self,name) -> None:
        super().__init__()
        self.name = name

    @property
    def name(self):
        return self.name  # 注意用下划线区分,避免深度递归

15.super的用法

super() 用法
用super()可以实现对父类成员的访问。
调用父类中被覆盖的方法,如:
super().method([paramlist])
调用父类的初始化函数,如:
super().init([paramlist])

16.多继承类的方法搜索顺序(python3)

python3为广度优先遍历(mro()),先搜索第一位继承类的方法,再搜索该类的其它方法,最后搜索第二位继承类的方法…

17.子类怎么对继承到的内容进行进一步重写

子类可以覆盖/重写父类成员方法

18.子类对象生成时需要生成的所有对象的具体过程

欲要有子,必先有父,父类的对象属性生成完,才能参数子类的对象属性。

19.多态的含义

即一个名字具有多种语义。
在面向对象中指一个方法可以有多种实现版本。
类的多态表现为方法的多态
方法的多态:覆盖(override)。

覆盖(重写)要求条件:
1.父子类中
2.子类中的方法务必和父类的方法同名
3.参数个数应保持一致
4.其他的通通一样

20.多态的好处

增强代码可维护性
提高程序的扩展性
可以用一个参数管理具有鸭子模型的多个对象

21.如何辨识对象是否为本类对象

判断对象是否为某类实例
isinstance(o,cls):辨识o是否为cls对应类的实例或子类实例
print(isinstance(so, SubObject)) # True
print(isinstance(so, object)) # True

type(o)/o.class:按对象对应的具体类型来比对 最精确
print(type(so) is SubObject) # True
print(so.class is SubObject) # True
print(type(so) is object) # False
print(so.class is object) # False

22.如何辨识某类是否是某类的子类

issubclass(sub_cls, super_cls):辨识sub_cls是否为super_cls子孙类
print(issubclass(SubObject, object)) # True

23.如何按内容比对对象

运算符重载
‘_ _ eq__’, ==
‘_ _ ge__’, >=
‘_ _ gt__’, >
‘_ _ le__’, <=
‘_ _ lt__’, <
‘_ _ ne__’, !=

==比较是__eq__()魔法方法的返回值
__eq__()方法未显式在类中,若未重写,继承自object或自身父类
object中的__eq__()仍然比对对象的地址 so此时仍为False
若有需求认为对象内容相同即为相等 需要重写__eq__()class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass

    def __eq__(self, other):
        return self.name == other.name and self.age == other.age

此时:
print(s1 == s2)  # True

24.如何在直接输出对象时按格式自动解析输出

一般类中重写将对象解析为字符串
str’,

25.如何获取标识符内地址

id()

26.你都知道哪些魔法方法,说说作用

信息获取:
‘_ _ class__’, 获取类型
‘_ _ dir__’, 获取全描述
‘_ _ doc__’, 获取类及类中方法的注释
‘_ _ sizeof__’, 获取对象字节长度 默认返回引用长度32

属性相关:
删除对象对象属性时执行的方法
‘_ _ delattr__’,
获取找不到的属性时执行的方法
‘_ _ getattribute__’,
设置属性时执行的方法
‘_ _ setattr__’,

运算符重载
‘_ _ eq__’, ==
‘_ _ ge__’, >=
‘_ _ gt__’, >
‘_ _ le__’, <=
‘_ _ lt__’, <
‘_ _ ne__’, !=

集合相关:
‘_ _ hash__’,

构造:
‘_ _ new__’,

初始化:
‘_ _ init__’,

对象自动解析:
交互式时使用
‘_ _ repr__’,
一般类中重写将对象解析为字符串
‘_ _ str__’,

格式化对象时
‘_ _ format__’,

归约相关
‘_ _ reduce__’,
‘_ _ reduce_ex__’,

生成子类对象时:
‘_ _ init_subclass__’,

检测子类方法
‘_ _ subclasshook__’

27.如何为类和对象动态追加属性

Python允许动态组装class

class的实例属性和类属性甚至方法成员都可以动态添加
例:
class Student:
    pass

# 动态添加类属性
Student.stu_count = 0
print(Student.stu_count)  # 0

# 动态添加实例属性
s1 = Student()
s1.name = "张三"
print(s1.name)  # 张三
# 动态添加实例方法
def show():
    print("show info")
    pass
s1.info = show  # 添加实例方法
s1.info()
s2 = Student()
s2.info()  # error
# 注意:动态添加的实例属性只能当前对象使用 若需要所有对象都能使用,请使用类名.进行动态添加(这种方式动态添加的变量是类变量,动态添加的方法要看方法的形式)

# 修改上面的代码:
def show(self):
    print("show info")
    pass
Student.info = show  # 添加实例方法
s1.info()
s2 = Student()
s2.info()  # ok

# 删除动态追加的内容:
对象名追加对象属性
# del obj.a
delattr(obj,"a")

类名追加类属性
del Foo.b

类名追加对象方法
del Foo.o_fun

28.如何限定实例可追加的属性

限定属性:
语法:
class limit_class:
slots = (“可动态添加的实例属性名”, …, …)
作用:
限定对象的属性名列表,防止随意动态添加实例属性

案例:
class User:
    __slots__ = ("name", "age", "tel", "address")

    def __init__(self, name, age, tel) -> None:
        self.name = name
        self.age = age
        self.tel = tel
        pass


user1 = User("admin", 19, "18866668888")
user1.address = "郑州市经开区8888号"
print(user1.name)
# user1.money = 10000  # error 不能追加未出现在限定组内的属性

29.类属性及类方法的意义

类属性:
直接在class中声明的变量
例如:
class Student:
stu_count = 0
pass
stu_count即为类属性

特点:
1.可以在未创建类的对象前就用类名直接调用类属性
2.被所有对象共用

类方法:
语法:
@classmethod
def methodname(cls):
pass
cls和self类似,只是绑定的是class自身

作用:
1.在未产生对象的情况下即可使用类名访问
2.对类变量进行内部封装处理

30.静态函数的意义

函数声明在了类的内部,无法在方法内访问类的其他内容

语法:不能绑定self\cls
@staticmethod
def methodname():
pass

作用:
1.在未产生对象的情况下即可使用类名访问
2.管束类的生成:构造函数__new__
3.函数集
4.多用于设计模式中

31.构造函数和初始化方法的区别

通常来说,新式类进行实例化时,new 方法会返回当前类的实例,然后调用该类的 init 方法进行实例的初始化。但是,如果 new 方法返回的不是当前类的实例,那么,当前类的 init 方法就不会被调用。
个人理解:构造函数打造模板,开辟内存空间,初始化根据模板生成对象实例初始化。

32.单例模式步骤有哪些

from typing import Any


class Book:
    def __new__(cls, name) -> Any:
        print("类的构造开始执行 ,对象出生")
        return super().__new__(cls)

    def __init__(self, name) -> None:
        super().__init__()
        self.name = name
        print("初始化方法执行了")

    def __str__(self):
        return self.name


class BookDb:
    _instance = None
    _init_flag = False

    def __new__(cls) -> Any:
        if cls._instance is None: #判定是否开辟过地址空间
            cls._instance = super().__new__(cls) #开辟地址空间,把地址给_instance
        return cls._instance #已经开辟地址空间,给它_instance的地址

    def __init__(self) -> None:
        if not BookDb._init_flag:
            super().__init__()
            self.__books = []
            BookDb._init_flag = True # 确定只产生一个对象

    def add_book(self, book):
        self.__books.append(book)

    def show_books(self):
        for i in range(len(self.__books)):
            print(self.__books[i])


book_db = BookDb()
book_db.add_book(Book("红与黑"))

# 若此时有另外的程序也需要书籍仓库
book_db2 = BookDb()
book_db2.add_book(Book("编程从精通到放弃"))

# book_db.show_books()
book_db2.show_books()

33.类定义时请小心深度递归

封装属性时,注意用下划线区分开来。

    @property
    def name(self):
        return self.name  # 注意用下划线区分,避免深度递归

附加 == VS is

对于不可变类型:
==一般情况下比较value
a = 10
b = 10
# so:
a == b  # True

is比较标识符内存放的地址
id(var):可以获取标识符内地址
只要id(x)得到的数据一致即为True 反之为False
a = "1"
b = "1"
print("a内地址:", id(a))
# a内地址: 2940295543976
print("b内地址:", id(b))
# b内地址: 2940295543976
print(a is b)  # True

可变类型:对象类型
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        pass
s1 = Student("zhangsan", 17)
s2 = Student("zhangsan", 17)
is仍然比对地址及id(x)的值 所以仍然为False
==比较是__eq__()魔法方法的返回值
__eq__()方法未显式在类中,若未重写,继承自object或自身父类
object中的__eq__()仍然比对对象的地址 so此时仍为False
若有需求认为对象内容相同即为相等 需要重写__eq__()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值