阿坝网站设计,三亚最新发布,上海网站建设内容更新,男生必备的浏览器面向对象编程#xff08;OOP#xff09;
一.类与实例
1.类#xff1a;
是对现实世界描述的一种类型#xff0c;是抽象的#xff0c;是实例的模板#xff0c;类名采用大驼峰#xff0c;定义方式为 class 类名: pass 。
2.实例#xff1a;
根据类创建的具体对象OOP
一.类与实例
1.类
是对现实世界描述的一种类型是抽象的是实例的模板类名采用大驼峰定义方式为 class 类名: pass 。
2.实例
根据类创建的具体对象通过类名加括号类名()创建。实例是具体的内容依赖于类。
3.self
在类的方法中self 代表调用该方法的实例本身在类内来代表未来的实例。通过 self 可以访问实例的属性和其他方法。 二.初始化函数 __init__
这是类的特殊方法通过初始化 self 来初始化未来的实例向 self 中添加数据就是向实例中添加数据。 运行结果 三.魔法函数特殊方法
这些方法允许对象进行特定的操作如字符串表示__str__、长度计算__len__、比较__eq__, __ne__ 等和算术运算__add__, __sub__ 等。 class MyClass:def __init__(self, name, age):print(f初始化函数执行了)self.name nameself.age agedef __str__(self):return f醒醒了:{self.name}def __len__(self):return len(self.name)def __eq__(self, other):return self.age other.agedef __ne__(self, other):return self.age ! other.agedef __gt__(self, other):return self.age other.agedef __ge__(self, other):return self.age other.agedef __lt__(self, other):return self.age other.agedef __le__(self, other):return self.age other.agedef __add__(self, other):return self.age other.agedef __sub__(self, other):return self.age - other.agedef __mul__(self, other):return self.age * other.agedef __divmod__(self, other):return divmod(self.age, other.age)def __mod__(self, other):return self.age % other.agedef __truediv__(self, other):return self.age / other.agedef __floordiv__(self, other):return self.age // other.agemc MyClass(张飞, 18)
print(mc)
print(len(mc))mc2 MyClass(孙尚香, 18)
print(mc mc2, mc ! mc2, mc mc2, mc mc2, mc mc2, mc mc2)print(mc mc2, mc - mc2, mc * mc2, mc % mc2, divmod(mc, mc2), mc / mc2, mc // mc2)运行结果 四.构造函数与析构函数
构造函数用于创建实例self并返回实例可通过父类来创建实例super().__new__() 。析构函数__del__ 方法在对象被销毁时调用用于执行清理工作。实例不再使用销毁之前执行。 运行结果: 五.三大特性
封装
包括数据如名字、年纪及数据相关的操作如获取名字、设置名字、获取年纪、设置年纪。 Light 灯
数据 state
操作 is_open change_state
class Light:def __init__(self):self.state False # 初始灯的状态为关闭self.colors [红色, 绿色, 蓝色] # 定义了三种颜色红色、绿色、蓝色self.current 0 # 初始颜色索引为0即红色def is_open(self):return self.state # 返回当前灯的状态True 表示开启False 表示关闭def change_state(self):self.state not self.state # 切换灯的状态如果是开启就关闭如果是关闭就开启def get_color(self):return self.colors[self.current] # 返回当前灯的颜色def set_color(self):self.current 1 # 切换到下一个颜色if self.current len(self.colors): # 如果颜色索引超过了颜色列表长度self.current 0 # 则重新回到第一个颜色# 示例用法
l0 Light()
# 初始状态
print(l0.is_open()) # 输出: False灯是关闭的
print()
# 切换状态
l0.change_state()
print(l0.is_open()) # 输出: True灯现在是开启的
print()
# 再次切换状态
l0.change_state()
print(l0.is_open()) # 输出: False灯又关闭了
print(l0.get_color()) # 输出: 红色因为当前颜色索引是0
print()
# 切换颜色
l0.set_color()
print(l0.get_color()) # 输出: 绿色因为当前颜色索引现在是1
print()
l0.set_color()
print(l0.get_color()) # 输出: 蓝色因为当前颜色索引现在是2
print()
l0.set_color()
print(l0.get_color()) # 输出: 红色因为当前颜色索引超过了列表长度重新回到0
print()
l0.set_color()
print(l0.get_color()) # 输出: 绿色依次循环显示颜色
运行结果 继承
子类拥有父类的数据以及操作子类不需要重新编写。Python 支持多继承而 Java、C# 只支持单继承通过接口等来实现多继承的功能。 多继承:
class MoveAble:def __init__(self, speed):self.speed speeddef move(self):print(fI can move, my speed is {self.speed}m/s)def __str__(self):return 我是移动类class SpeakAble:def __init__(self, language):self.language languagedef speak(self):print(fI can speak {self.language})def __str__(self):return 我是说话类class AttackAble:def __init__(self, skill):self.skill skilldef attack(self):print(f使用{self.skill}发起攻击)def __str__(self):return 我是攻击类class Person(MoveAble, SpeakAble):def __init__(self, name, speed, language):# super().__init__() 会执行第一个父类# super().__init__(speed)# 通过类名表名 需要初始化哪个父类 必须传入selfMoveAble.__init__(self, speed)SpeakAble.__init__(self, language)self.name namedef show(self):print(fmy name is {self.name})def __str__(self):return 我是人类p0 Person(小张, 50, 汉语)
p0.show()
p0.move()
p0.speak()多态
Python 中可以理解到处都是多态有两种形式一是函数同名不同参数通过 *args 实现二是父子类多态函数名参数都相同但实现不同。 运行结果: 六.抽象类
是特殊的类内部可编写抽象方法不能直接实例化也可编写普通实例方法。子类继承抽象类必须实现抽象类的抽象方法 抽象类不直接实例化 通过子类来产生实例from abc import ABC, abstractmethodclass Animal(ABC):抽象类:拥有抽象方法 不能直接实例化通过装饰器abstractmethod把 walk 变为抽象方法abstractmethoddef walk(self):passdef eat(self):print(f可以吃)# a0 Animal()
# print(a0, isinstance(a0, Animal))class Dog(Animal):抽象类子类 必须实现抽象类中的抽象方法def walk(self):print(f摇摇尾巴)dog Dog()
dog.eat() # 调用继承自 Animal 的 eat() 方法
print(isinstance(dog, Dog), isinstance(dog, Animal)) # 检查实例的类型class Cat(Animal):def walk(self):print(f跳来跳去)cat Cat()
cat.eat() # 调用继承自 Animal 的 eat() 方法
print(isinstance(cat, Cat), isinstance(cat, Animal)) # 检查实例的类型七.类中内容
实例属性向实例中添加的数据类内通过 self类外通过实例。实例方法第一个形参是 self类内通过 self类外通过实例类属性向类中添加数据获取与设置直接通过类名通过实例获取不推荐实例不能设置类属性。类方法第一个形参一般是 cls带有装饰器 classmethod目的是获取类相关信息实例可以获取类方法但不推荐。静态方法没有特殊形参带有装饰器 staticmethod通过类名调用实例可以访问但不推荐项目的辅助类一般使用静态方法。
class Person:MAX_ACE 100 # 类属性最大值MIN_ACE 0 # 类属性最小值classmethoddef from_birth_year(cls, name, birth_year):current_year 2024 # 假设当前年份是 2024age current_year - birth_yearreturn cls(name, age) # 返回一个新的 Person 实例staticmethoddef is_adult(age):return age 18 # 静态方法判断是否成年def __init__(self, name, age):self.name name # 实例属性姓名self.age age # 实例属性年龄def __str__(self):return f名字:{self.name}, 年龄:{self.age} # 返回对象描述的字符串def set_name(self, name):self.name name # 设置姓名的实例方法def get_name(self):return self.name # 获取姓名的实例方法# 创建一个 Person 对象
p0 Person(张飞, 20)
# 输出对象的 name 和 age 属性
print(p0.name, p0.age) # 输出: 张飞 20
# 使用 __str__ 方法打印对象的字符串表示
print(p0) # 输出: 名字:张飞, 年龄:20
# 使用 set_name 方法修改 name 属性
p0.set_name(关羽)
# 再次打印对象的字符串表示和获取名字
print(p0, p0.get_name()) # 输出: 名字:关羽, 年龄:20# 访问类属性
print(Person.MAX_ACE) # 输出: 100
print(Person.MIN_ACE) # 输出: 0# 修改类属性
Person.MIN_ACE 10
print(Person.MIN_ACE) # 输出: 10# 通过实例访问类属性不推荐这样做
print(p0.MIN_ACE, p0.MAX_ACE) # 输出: 10 100# 尝试通过实例修改类属性这不会修改类的属性而是创建了一个实例属性
p0.MAX_ACE 200
print(Person.MIN_ACE, p0.MAX_ACE) # 输出: 10 200# 使用类方法创建 Person 对象
p2 Person.from_birth_year(关羽, 1990)
print(p2) # 输出: 名字:关羽, 年龄:34# 使用静态方法判断年龄是否成年
print(Person.is_adult(20)) # 输出: True
print(Person.is_adult(15)) # 输出: False 八.动态添加内容
Python 的动态性允许在运行时向类中添加新的属性、方法等。
import typesclass Person:pass# # 在实例上添加属性 向实例中添加实例数据 其他实例无影响
p0 Person()
p Person()
p.name 赵云
print(p.name)# 添加实例方法 # 向实例中添加实例数据 其他实例无影响
def my_set_name(self, name):self.name namep.set_name types.MethodType(my_set_name, p)
p.set_name(关羽)
print(p.name)
# 向类中添加类属性 类可以正常访问 所有实例均可访问
Person.MAX_AGE 120
print(Person.MAX_AGE, p.MAX_AGE, p0.MAX_AGE)classmethod
def my_info(cls):print(cls.__bases__)# 向类中添加类方法 方法格式符合类方法格式 类与所有实例均可访问
Person.info my_info
Person.info()
p0.info()
p.info()staticmethod
def my_max(x, y):return x if x y else y# 向类中添加静态方法 方法要符合静态方法格式 类与实例均可访问
Person.max my_maxprint(Person.max(10, 20), p.max(50, 100), p0.max(200, 500)) 九.数据的访问级别
公有普通名字类内、类外、子类都可以使用。。私有以双下划线 __ 开头的属性或方法在类外部不能直接访问但可以通过类的公有方法间接访问。保护Python 中不严格区分以单下划线 _ 开头的属性或方法遵在类内可以访问在子类可以访问在类外可强制访问。 数据的访问级别公有类型public普通名字类内和类外,子类都可以使用私有类型private以_ _开头只能在类内访问保护类型protect在类内可以访问在子类中可以访问在类外可以强制访问
class Person:def __init__(self, name, age, sex):self.name nameself.__age ageself._sex sexdef _set_sex(self, sex):self._sex sexdef _get_sex(self):return self._sexdef __set_age(self, age):self.__age agedef __get_age(self):return self.__agedef get_name(self):return self.namedef set_name(self, name):self.name namedef __str__(self):return fname:{self.name},age:{self.__age},sex:{self._sex}# 公有
p0 Person(张飞, 20, 男) # 私有只能在类内访问 age
print(p0)
p0.set_name(张菲菲)
print(p0.name, p0.get_name())
# 保护
p0._set_sex(女)
print(p0._get_sex()) 十.属性封装与 property
口头称呼类封装数据与操作属性与行为包括类属性、实例属性、公有属性、私有属性、保护属性。property 包括 fget获取触发property和 fset设置触发属性名.setter装饰器。
class Person:def __init__(self, name, age, sex, height):self.__name nameself.age ageself.__sex sexself.__height heightpropertydef height(self):return self.__heightheight.setterdef height(self, height):self.__height heightdef __get_sex(self):return self.__sexdef __set_sex(self, sex):if sex in [男, 女]:self.__sex sexelse:print(设置失败)# 封装真正的属性sex property(__get_sex, __set_sex)def get_name(self):return self.__namedef set_name(self, name):if 2 len(name) 4:self.__name nameelse:print(设置失败)p Person(张飞, 20, 男, 190)# 获取 设置age 直接使用 (容易产生不合法数据)
print(p.age)
p.age -30
print(p.age)
print()
# 获取设置name 需要通过函数 数据安全
print(p.get_name())
p.set_name(赵云)
print(p.get_name())
print()
# 使用 property 获取和设置 sex
print(p.sex)
p.sex 其他
print(p.sex)
print()
print(p.height)
p.height 200
print(p.height) 十一.单例模式
只有一个实例通过控制构造函数判定是否需要重新生成实例第一次生成后放入类属性以后返回第一次生成的实例。
class Person:pass# 每次调用类都可以生成一个新的实例
p1 Person()
p2 Person()
p3 Person()print(p1 is p2, p2 is p3, p3 is p1)class Manage(object):instance Nonedef __new__(cls, *args, **kwargs):对构造函数进行控制 不是每次都生成新的实例1. 对类属性instance判断 如果为空 就构造一个实例 并且把实例赋予instance2. 对类属性instance判断 如果不为空 则直接把他返回if not Manage.instance:Manage.instance super().__new__(cls)return Manage.instancedef __init__(self):初始化函数 初始化实例 向self中添加内容print(f初始化函数执行了)m1 Manage()
m2 Manage()
print(m1 is m2, m1 is None, m2 is None)class BaseManage:def __new__(cls, *args, **kwargs):if not hasattr(BaseManage, instance):obj super().__new__(cls)setattr(BaseManage, instance, obj)return getattr(BaseManage, instance)m1 BaseManage()
m2 BaseManage()
print(m1 is m2)class SystemManage(BaseManage):passsm1 SystemManage()
sm2 SystemManage()
print(sm1 is sm2)
print(isinstance(sm1, SystemManage), isinstance(sm1, BaseManage))