文章目录
- 六.Python高级语法
- 4.面向对象编程
- 4.2类方法和类属性
- 4.2.1类属性
- 4.2.2类方法
- 4.3普通方法和类方法在调用时的区别
- 4.4静态方法
- 4.5构造方法\__new__()
- 4.6魔术方法介绍
- 4.6.1常用方法
- 4.6.2案例实现
- 5.OOP基本特征
- 5.1封装
- 5.2继承
- 5.2.1继承/派生名词:
- 5.2.2语法
六.Python高级语法
4.面向对象编程
4.2类方法和类属性
4.2.1类属性
- 在对象没有创建 和类属性同名属性时,类和对象调用的类属性是同一个
- 创建了同名属性 就相互独立了
- 示例:
class Box:
x = 100
def __init__(self,name):
self.name = name
b1 = Box("张三")
print(b1.x is Box.x) # 输出 True
class Box2:
x = 100
def __init__(self,name,x):
self.name = name
self.x = x # 创建了 和类属性同名属性
b2 = Box2("张三",200)
print(b2.x is Box2.x) # 输出 False
4.2.2类方法
- 类方法需要使用@classmethod装饰器定义
- 类方法至少带有一个形参,用于绑定类,约定cls
类方法不能访问 此类创建的对象的实例属性
- 实例:
class Box:
x = 100
def __init__(self,name):
self.name = name
# 必须使用装饰器
@classmethod
def cm(cls,x):# 必须带有一个绑定类的形参
cls.x = x
b1 = Box("张三")
Box.cm(200) # 调用类方法 修改 类属性
4.3普通方法和类方法在调用时的区别
- 一般为了区分,类只调类方法,对象只调普通方法
- 但是 普通方法和类方法 都可以被类和对象调用
- 只是在调用时 语法有点区别。示例:
class Box:
x = 100
def __init__(self,name):
self.name = name
def ordinary(self):
print(self.x)
@classmethod
def cm(cls,x):
cls.x = x
print(cls.x)
b1 = Box('张三') # 创建的类和对象
# 调用普通方法时
#对象调
b1.ordinary() # 隐式操作 => ordinary( b1 ) 输出100
#类调(不建议)
Box.ordinary( b1 ) # 没有隐式操作 必须传参数(类/对象) 输出100
# 调用类方法时
#对象调(不建议)
b1.cm(200) # 隐式操作 => cm( Box ) 输出200
#类调
Box.cm(300) # 隐式操作 => cm( Box ) 输出300
4.4静态方法
- 使用@staticmethod装饰器定义——常用于工具函数
- 不需要self和cls参数,通过类或类实例调用
- 可以访问类属性,不能访问实例属性
- 示例:
class Box:
x = 100
@classmethod # 类方法
def cm(cls):
cls.fz() # 调用静态方法
@staticmethod # 静态方法
def fz():
print('我是静态方法')
Box.cm() # 输出 我是静态方法
Box.fz() # 输出 我是静态方法
4.5构造方法_new_()
- 负责对象的 创建 和内存分配的。
- 在对象实例化时被调用,负责返回一个新的对象实例。
- 通常不需要显式地定义
__new__()
方法,Python会调用基类 o b j e c t object object 的__new__()
方法。
4.6魔术方法介绍
- 魔术方法是一种特殊的方法,用双下划线包裹,例如
__init__
,__str__
,__add__
等 - 这些方法允许自定义类的行为,方便与Python内置功能(如+运算符、迭代、字符串表示等)交互
4.6.1常用方法
方法名 | 说明 |
---|---|
__init__(self, ...) | 在创建对象时,用于设置对象的属性(初始化) |
__str__(self) | 方法的返回值 = print(object) 的输出值 |
__repr__(self) | 和str类似,通过repr(对象)调用,输出字符串 |
__delitem__(self, key) | 定义对象的删除操作,例如,执行del object[key] 时,就会调用该方法 |
常用__len__(self) 和、__getitem__(self, key) 和、__setitem__(self, key, value) | 分别执行 len(object) 、 obj [ key] 和 obj [ key] = value 触发 |
__add__(self,other) | 执行 对象1 + 对象2 时触发 |
__sub__(self, other) | 执行 `对象1 - 对象2时触发 |
__eq__(self, other) | 执行 对象1 == 对象2时触发 |
__lt__(self, other) | 执行 对象1 < 对象2时触发 |
__gt__(self, other) | 执行 对象1 > 对象2时触发 |
4.6.2案例实现
-
__str__()
:定义print()
或str()
函数调用时的输出值(字符串形式)- 该方法必须返回一个字符串,通常用于给用户可读的对象描述
class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return f"name is: {self.name}, Age is: {self.age}" # 创建对象 p p = Person("张三", 18) print(p) # 输出: name is: 张三, Age is: 18
-
__delitem__(self, key)
:class Person: def __init__(self, name, age): self.name = name self.age = age def __delitem__(self,key): del self.name # key未使用,适合删除有索引的数据 # 创建对象 p p = Person("张三", 18) # 这个语法触发__delitem__魔术方法 del p['name'] print(p.name) # 报错,name不存在
-
__len__(self)
和__getitem__(self, key)
和__setitem__(self, key, value)
:class Image: def __init__(self,path): self.path = path self.arr=["1.jpg","2.jpg","3.jpg"] def __len__(self): return len(self.arr) # 自己决定返回什么 def __setitem__(self,key,value): self.arr[key] = value # 自己决定修改哪个 可变容器 def __getitem__(self,key): return self.arr[key] # 自己决定取什么值 image = Image("./") count = len(image) # 触发条件 print(count) # 输出 3 image[0] = '我被修改了' # 触发条件 re = image[0] # 触发条件 print(re) # 输出 我被修改了
-
__add__(self,other)
:
class Person:
def __init__(self, money):
self.money = money
def __add__(self,other):
return(self.money+other.money)
p1 = Person(100)
p2 = Person(200)
re = p1+p2 # 触发条件 ==》 p1 = self ; p2 = other
print(re) # 输出300
5.OOP基本特征
面向对象编程(Object-Oriented Programming,简称OOP)的四大基本特征是封装、继承、多态和抽象
5.1封装
-
封装是指将对象的属性和方法包装在一起,对外隐藏实现细节,只提供必要的接口给外部访问。
-
以
__
开头的属性或方法是私有的,在子类和类外部无法直接使用
5.2继承
5.2.1继承/派生名词:
- 基类(base class)/超类(super class)/父类(father class)
- 派生类(derived class)/子类(child class)
5.2.2语法
- class 类名(继承类, …): 继承类为父类
- 单继承
- 通过 super( ).__init__(参数名, …) 继承父类的初始化方法——固定写法
- 示例:
class Animal: # 父类
def __init__(self,name):
self.name = name
def eat(self):
print("{}在吃东西".format(self.name))
class Dog(Animal):
def __init__(self,name,school):
super().__init__(name) # 继承父类的初始化方法——固定写法
self.school =school # 添加父类没有的属性
dog = Dog("旺财",'502')
dog.eat() # 自己没有,直接调用1父类方法
- 多继承
- 通过多个 父类名.__init__(self, 参数…) 这样的方式继承多个父类的初始化值
- 示例:
class Father:
def __init__(self,eat):
self.money = 1000
self.eat = eat
class Mother:
def __init__(self):
self.car = "小车"
class Son(Father, Mother):
def __init__(self,eat):
Father.__init__(self,eat)
Mother.__init__(self)
self.school = "502"
s = Son('fruit')
print(s.money) # 输出 1000
print(s.car) # 输出 小车
print(s.eat) # 输出 fruit
print(s.school) # 输出 502