文章目录
1. 组合
组合是面向对象编程中的一个重要概念,它允许一个类(或对象)包含其他类(或对象)作为其成员。这种关系是一种强关联关系,通常表现为一个类(或对象)拥有另一个类(或对象)的实例作为其一部分。
示例:
class Engine:
def start(self):
print("Engine started")
class Car:
def __init__(self):
self.engine = Engine() # 使用组合关系,将Engine类的实例作为Car类的一个成员
def start(self):
self.engine.start()
# 使用示例
my_car = Car()
my_car.start() # 输出: "Engine started"
什么场景下使用继承? 什么场景下使用组合?
- 继承一般情况用在:什么是什么的情况 is
- 组合一般用在:什么有什么的情况 has
示例如下:
class People():
school = 'SH'
def __init__(self, name, age, gender, course_name=None, course_price=None, course_period=None):
self.name = name
self.age = age
self.gender = gender
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period
class Admin(People):
def __init__(self, name, age, gender):
super().__init__(name, age, gender)
class Course():
def __init__(self, name, price, period):
self.name = name
self.price = price
self.period = period
python=Course('python', 10000, '6mon')
linux=Course('linux', 20000, '5mon')
# print(python.name)
# print(python.price)
# print(python.period)
class Student(People):
def __init__(self, name, age, gender, course=None):
super().__init__(name, age, gender)
if course is None:
course = []
self.course = course
stu = Student('kevin', 20, 'male')
stu.course.append(python.name)
stu.course.append(linux.name)
print(stu.course) # [<__main__.Course object at 0x000001F258F86B80>, <__main__.Course object at 0x000001F258F511C0>]
# stu.course: []
for i in stu.course:
print(i)
class Teacher(People):
def __init__(self, name, age, gender, level):
super().__init__(name, age, gender)
self.level = level
tea = Teacher('ly', 19, 'female', 10)
print(tea.course_name)
tea.course=linux
print(tea.course.name)
print(tea.course.price)
2.反射
在Python中,反射指的是通过字符串来操作对象的属性。设计一下四个函数:
2.1 getattr
getattr(obj, name[, default])
:获取对象的属性或方法。如果属性或方法不存在,可以提供一个默认值。
class MyClass:
def my_method(self):
print("Hello!")
obj = MyClass()
method = getattr(obj, 'my_method')
method() # 输出: Hello!
2.2 setattr
setattr(obj, name, value)
:设置对象的属性值或方法。
class MyClass:
pass
obj = MyClass()
setattr(obj, 'my_attribute', 42)
print(obj.my_attribute) # 输出: 42
2.3 hasattr
hasattr(obj, name)
:检查对象是否有某个属性或方法。
class MyClass:
pass
obj = MyClass()
print(hasattr(obj, 'my_attribute')) # 输出: False
2.3 delattr
delattr(obj, name)
:删除对象的属性或方法。
class MyClass:
my_attribute = 42
obj = MyClass()
delattr(obj, 'my_attribute')
print(hasattr(obj, 'my_attribute')) # 输出: False
3. 内置方法(魔方方法)
Python 中的“魔法方法”(也称为特殊方法或双下划线方法)是一类特殊命名的方法,它们以双下划线开头和结尾(例如 __init__)。这些方法在类中有特定的含义,它们会在特定的情况下自动被调用。
以下为一些常用的魔法方法:
3.1 init
__init__
:初始化方法,会在实例创建时自动调用。用于初始化对象的属性。
Class Student():
def __init__(self, name, age):
self.name = name
self.age = age
3.2 str, repr
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
"""
1. 打印对象的时候,输出对象的时候会自动触发类中得__str__方法
2. 返回值必须是字符串形式
3. 如果它跟__repr__方法同时存在,__str__的优先级更高
"""
def __str__(self): # 这个用的是最多的
print('str')
return 'from str'
def __repr__(self):
print('repr')
return 'from repr'
stu = Student('ly', 20)
# print(stu) # <__main__.Student object at 0x00000226AC4F5A60>
# print('repr:', repr(stu))
print('str:', str(stu))
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.f = open('a.txt', 'w')
"""
1.当你删除对象的时候会触发__del__的执行
2. 当整个脚本的程序都执行完毕的时候,也会触发__del__的执行
3. 一般用在用来在对象被删除时自动触发回收系统资源的操作
"""
def __del__(self):
print('from _del')
self.f.close()
mysql = MySQL('127.0.0.1', 3306)
print('1223')
print('1223')
print('1223')
print('1223')
print('1223')
print(isinstance(123, str))
print(type(123) is int)
class Foo:
pass
class Bar(Foo):
pass
class Bar1():
pass
print(issubclass(Bar1, Foo))
class Foo:
"""
'我是描述信息asdasd'
'我是描述信息asdasd'
'我是描述信息asdasd'
"""
pass
class Bar(Foo):
pass
print(Bar.__doc__)
3.3 enter 和 exit
class Open:
def __init__(self, name):
self.name = name
def __enter__(self):
print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
# return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('with中代码块执行完毕时执行我啊')
"""with它可以用在很多地方,但是,出现with语句后面的对象中得类必须要声明__enter__和__exit__"""
with Open('a.txt') as f:
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
# print(f,f.name)
简答题:先聊聊with 的用法? 问with上下文管理协议的执行原理? 为什么打开文件只会可以自动关闭?请说出原因
class Open:
def __init__(self, name):
self.name = name
def __enter__(self):
print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
# return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('with中代码块执行完毕时执行我啊')
print(exc_type) # 异常类型
print(exc_val) # 异常值
print(exc_tb) # 追溯信息
return True # 如果你在这个方法里面返回了True,with代码块中出现了异常,就相当于没有出现异常
"""with它可以用在很多地方,但是,出现with语句后面的对象中得类必须要声明__enter__和__exit__"""
# with Open('a.txt') as f:
# print('=====>执行代码块')
# print('=====>执行代码块')
# print('=====>执行代码块')
# print('=====>执行代码块')
# print('=====>执行代码块')
# # print(f,f.name)
"""如果with代码块中出现了异常,则with语句之后的代码都不能正常执行"""
with Open('a.txt') as f:
print('=====>执行代码块')
raise AttributeError('***着火啦,救火啊***') # 抛出异常,主动报错
print('0'*100) #------------------------------->不会执行
3.4 setattr, delattr, getattr
__setattr__,__delattr__,__getattr__
class Foo:
x=1
def __init__(self,y):
self.y=y
"""当你找的属性不存在的时候,会触发__getattr__,但是必须是点语法的时候才会"""
def __getattr__(self, item):
print('----> from getattr:你找的属性不存在')
def __setattr__(self, key, value):
print('----> from setattr')
# self.key=value # self.a=20
# self.key=value #这就无限递归了,你好好想想
self.__dict__[key]=value #应该使用它
def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了
self.__dict__.pop(item)
obj=Foo(10)
# obj.z
obj.a=20
print(obj.a)
del obj.a
3.5 setitem, getitem, delitem
__setitem__,__getitem,__delitem__
class Foo:
def __init__(self, name):
self.name = name
"""当你通过中括号获取对象的属性的时候,会自动触发__getitem__"""
def __getitem__(self, item):
print('__getitem__')
print(self.__dict__[item])
def __setitem__(self, key, value):
# key:age
# value:18
print('__setitem__')
self.__dict__[key] = value
# self.__dict__['age'] = 18
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
pass
# def __delattr__(self, item):
# print('del obj.key时,我执行')
# self.__dict__.pop(item)
obj=Foo('tom')
# print(obj.name)
# obj['name']
obj['age'] = 18
# obj.age=18
print(obj.age)
del obj['age']
3.6 call
class Foo:
def __init__(self):
pass
#### 当对象加括号的时候会触发__call__的执行
def __call__(self, *args, **kwargs):
print('__call__')
obj=Foo()
print(obj)
obj()