快速学习Python基础知识详细图文教程10--类和对象1
来源引用网络知识与某站曹老师视频相互结合学习记录,仅供参考!
Python 基础知识
类和对象
在现实生活中,人是抽象的类,简称人类,像是“张三、李四、王五。。。。。。”,这样真真正正存在人的实体,称这些实体称为对象。
1、 初识 Python 类和对象
在面向对象的程序设计过程中有两个重要概念:类(class)和对象(object,也被称为实例 instance)
其中类是某一批对象的抽象,可以把类理解成某种概念;对象才是一个具体存在的实体。
Python 中类的基本定义:
class 类名:
零个或者多个属性
零个或者多个方法
# 定义人类--class 关键字 加上 类名 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 创建一个对象 zhangsan zhangsan = Person() zhangsan.name = '张三' zhangsan.age = 15 print(f'zhangsan name is {zhangsan.name}, age is {zhangsan.age}') # 再创建一个对象 lisi lisi = Person() lisi.name = '李四' lisi.age = 20 print(f'lisi name is {lisi.name}, age is {lisi.age}') 控制台输出运行结果: zhangsan name is 张三, age is 15 lisi name is 李四, age is 202、 类的成员方法
类中有属性,用来记录对象数据;类中也有方法,用来描述对象的行为;在类的内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例;
类里面访问成员变量,可以用 self 关键字,在定义成员方法的时候,self 关键字必须填写;self 表示当前的类对象,self 代表类的实例,而非类;类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self;
在 Python中,self 是一个惯用的名称,用于表示类的实例(对象)自身。它是一个指向实例的引用,使得类的方法能够访问和操作实例的属性。当定义一个类,并在类中定义方法时,第一个参数通常被命名为 self,尽管你可以使用其他名称,但强烈建议使用 self,以保持代码的一致性和可读性。
# 定义人类--class 关键字 加上 类名 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 成员方法--say--打印输出当前对象的姓名和年龄 def say(self): print(f'姓名:{self.name},年龄:{self.age}') # 创建一个对象 zhangsan zhangsan = Person() zhangsan.name = '张三' zhangsan.age = 15 zhangsan.say() 控制台输出运行结果: 姓名:张三,年龄:15什么叫“当前对象”呢?其实就是说哪个对象调用的,那个对象就是当前对象;
# 定义人类--class 关键字 加上 类名 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 成员方法--say--打印输出当前对象的姓名和年龄 def say(self): print(f'姓名:{self.name},年龄:{self.age}') # 再定义一个成员方法--self 必填;再跟一个内容msg def say2(self, msg): # “备注:{msg}”这个 msg 不是Person类里面的属性,是调用方法传过来的,所以可以直接使用 print(f'姓名:{self.name},年龄:{self.age},备注:{msg}') # 创建一个对象 zhangsan zhangsan = Person() zhangsan.name = '张三' zhangsan.age = 15 zhangsan.say() zhangsan.say2('未成年') # 再创建一个对象 lisi lisi = Person() lisi.name = '李四' lisi.age = 20 lisi.say() lisi.say2('成年人') 控制台输出运行结果: 姓名:张三,年龄:15 姓名:张三,年龄:15,备注:未成年 姓名:李四,年龄:20 姓名:李四,年龄:20,备注:成年人3、 类的构造方法
Python 类里的 __init__ 方法就是类的构造方法,用作构造对象,同时还可以给对象初始化属性值用。
假如类里面没有写 init 构造方法,默认会提供一个空的构造方法。
1、构造对象使用;
# 定义人类--class 关键字 加上 类名 class Person: # 属性 姓名 name = None # 属性 年龄 age = None def __init__(self): print('构造方法') # 成员方法--say--打印输出当前对象的姓名和年龄 def say(self): print(f'姓名:{self.name},年龄:{self.age}') # 再定义一个成员方法--self 必填;再跟一个内容msg def say2(self, msg): # “备注:{msg}”这个 msg 不是Person类里面的属性,是调用方法传过来的,所以可以直接使用 print(f'姓名:{self.name},年龄:{self.age},备注:{msg}') # 创建一个对象 zhangsan zhangsan = Person() zhangsan.name = '张三' zhangsan.age = 15 zhangsan.say() zhangsan.say2('未成年') # 再创建一个对象 lisi lisi = Person() lisi.name = '李四' lisi.age = 20 lisi.say() lisi.say2('成年人') 控制台输出运行结果: 构造方法 姓名:张三,年龄:15 姓名:张三,年龄:15,备注:未成年 构造方法 姓名:李四,年龄:20 姓名:李四,年龄:20,备注:成年人2、给对象初始化属性值使用;
# 定义人类--class 关键字 加上 类名 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # def __init__(self): # print('构造方法') # 调用构造方法时,把“name和age”进行初始化 def __init__(self, name, age): print('调用有参构造方法') # 当前对象的name值用传过来的“name”(调用构造方法传过来的初始化值) self.name = name self.age = age # 成员方法--say--打印输出当前对象的姓名和年龄 def say(self): print(f'姓名:{self.name},年龄:{self.age}') # 再定义一个成员方法--self 必填;再跟一个内容msg def say2(self, msg): # “备注:{msg}”这个 msg 不是Person类里面的属性,是调用方法传过来的,所以可以直接使用 print(f'姓名:{self.name},年龄:{self.age},备注:{msg}') # 创建一个对象 zhangsan zhangsan = Person('zhangsan', 15) # zhangsan.name = '张三' # zhangsan.age = 15 zhangsan.say() zhangsan.say2('未成年') # 再创建一个对象 lisi lisi = Person('lisi', 20) # lisi.name = '李四' # lisi.age = 20 lisi.say() lisi.say2('成年人') 控制台输出运行结果: 调用有参构造方法 姓名:zhangsan,年龄:15 姓名:zhangsan,年龄:15,备注:未成年 调用有参构造方法 姓名:lisi,年龄:20 姓名:lisi,年龄:20,备注:成年人4、 魔法方法
Python 的魔法方法,也称为特殊方法或双下划线方法,是一种特殊的方法,用于在类中实现一些特殊的功能。这些方法的名称始终以双下划线开头和结尾,例如 init、repr、add 等。
魔法方法(部分特殊方法) | 描述 |
__init__(self[, args...]) | 构造函数,创建一个新对象时调用,其中 self 代表当前类的一个实例对象。 |
__del__(self) | 析构函数,析构器,删除一个对象,当对象被(销毁)删除时调用。 |
__repr__(self) | 定义对象的字符串表示,通过重载该方法可以自定义输出对象的字符串表示。 |
__str__(self) | 定义对象的字符串表示,与 __repr__ 功能相同,但是在打印对象的 str()方法调用时被调用。 |
__bytes__(self) | 定义对象的字节表示,用于调用 bytes()内置函数时调用。 |
__format__(self, format_spec) | 定义格式化字符串,与 format() 内置函数结合使用。 |
__hash__(self) | 定义对象的哈希值,用于在字典、集合等数据结构中使用。 |
__bool__(self) | 定义对象的布尔值,该方法必须返回 True 或 False。 |
__getattr__(self, item) | 动态返回某个属性的值。 |
__setattr__(self, key, value) | 动态返回某个属性的值。 |
__eq__(self, other) | 定义对象间的等于操作,当使用 == 比较两个对象时被调用。 |
__ne__(self, other) | 定义对象间的不等于操作,当使用 != 比较两个对象时被调用。 |
__lt__(self, other) | 定义对象间的小于操作,当使用 < 比较两个对象时被调用。 |
__le__(self, other) | 定义对象间的小于等于操作,当使用 <= 比较两个对象时被调用。 |
__gt__(self, other) | 定义对象间的大于操作,当使用 > 比较两个对象时被调用。 |
__ge__(self, other) | 定义对象间的大于等于操作,当使用 >= 比较两个对象时被调用。 |
__add__(self, other) | 定义对象间的加法操作,当使用 + 运算符时被调用。 |
__sub__(self, other) | 定义对象间的减法操作,当使用 - 运算符时被调用。 |
__mul__(self, other) | 定义对象间的乘法操作,当使用 * 运算符时被调用。 |
__truediv__(self, other) | 定义对象间的除法操作,当使用 / 运算符时被调用。 |
__floordiv__(self, other) | 定义对象间的整除操作,当使用 // 运算符时被调用。 |
__mod__(self, other) | 定义对象间的取模操作,当使用 % 运算符时被调用。 |
__pow__(self, power, modulo=None) | 定义对象间的幂运算操作,当使用 ** 运算符时被调用。 |
__lshift__(self, other) | 定义对象间的左移位操作,当使用 << 运算符时被调用。 |
__rshift__(self, other) | 定义对象间的右移位操作,当使用 >> 运算符时被调用。 |
__add__(self, other) | 定义对象间的位与操作,当使用 & 运算符时被调用。 |
__or__(self, other) | 定义对象间的位或操作,当使用 | 运算符时被调用。 |
__xor__(self, other) | 定义对象间的异或操作,当使用 ^ 运算符时被调用。 |
__invert__(self) | 定义对象的按位取反操作,当使用 ~ 运算符时被调用。 |
__call__(self, *args, **kwargs) | 定义可调用对象,使实例对象可以像函数一样被调用。 |
常用的特殊方法
__str__ 方法,定义对象的显示字符串,默认是对象内存地址,一般可以通过重写 str 方法,显示所需要的数据信息。
# 定义类 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 构造器--初始化构造函数 def __init__(self, name, age): self.name = name self.age = age zhangsan = Person('张三', 15) # 直接打印--打印输出“内存地址”的表示 print(zhangsan) # 与上相同,不过每次执行时,输出打印的内存地址都会变 print(str(zhangsan)) 控制台输出结果: <__main__.Person object at 0x000001EAFFF4EA50> <__main__.Person object at 0x000001EAFFF4EA50>重新定义 str 方法;
# 定义类 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 构造器--初始化构造函数 def __init__(self, name, age): self.name = name self.age = age # 重新__str__方法 def __str__(self): # 返回值 return f'{self.name} is {self.age} years old' zhangsan = Person('张三', 15) # 直接打印--__str__方法返回值 print(zhangsan) print(str(zhangsan)) 控制台输出结果: 张三 is 15 years old 张三 is 15 years old__eq__ 方法用于定义对象间的等于操作,当使用==比较两个对象时被调用;
# 定义类 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 构造器--初始化构造函数 def __init__(self, name, age): print('调用有参构造方法') self.name = name self.age = age # 重新__str__方法 def __str__(self): print('调用__str__方法') # 返回值 return f'{self.name} is {self.age} years old' # self:是当前对象;other:第二对象(其他对象) def __eq__(self, other): print('调用__eq__方法') return self.age == other.age zhangsan = Person('张三', 15) # 直接打印--__str__方法返回值 print(zhangsan) lisi = Person('李四', 20) print(lisi) print(zhangsan == lisi) 控制台输出结果: 调用有参构造方法 调用__str__方法 张三 is 15 years old 调用有参构造方法 调用__str__方法 李四 is 20 years old 调用__eq__方法 False其他,通过重写魔法方法,实现 zhangsan < lisi 以及 zhangsan >= lisi 这两个对象通过属性 age 来判断大小,返回布尔类型。
# 定义类 class Person: # 属性 姓名 name = None # 属性 年龄 age = None # 构造器--初始化构造函数 def __init__(self, name, age): print('调用有参构造方法') self.name = name self.age = age # 重新__str__方法 def __str__(self): print('调用__str__方法') # 返回值 return f'{self.name} is {self.age} years old' # self:是当前对象;other:第二对象(其他对象) def __eq__(self, other): print('调用__eq__方法,等于操作') return self.age == other.age def __lt__(self, other): print('调用___lt_方法,小于操作') return self.age < other.age def __ge__(self, other): print('调用__ge__方法,大于等于操作') return self.age >= other.age zhangsan = Person('张三', 15) print(zhangsan) lisi = Person('李四', 20) print(lisi) print(zhangsan == lisi) print(zhangsan < lisi) print(zhangsan >= lisi) 控制台输出结果: 调用有参构造方法 调用__str__方法 张三 is 15 years old 调用有参构造方法 调用__str__方法 李四 is 20 years old 调用__eq__方法,等于操作 False 调用___lt_方法,小于操作 True 调用__ge__方法,大于等于操作 False未完待续......
