python基础面向对象(类、继承反射)

it2024-01-11  56

python第五节课

面向对象编程类self继承静态方法类的特殊成员方法反射

面向对象编程

编程 = 特定语法 + 数据结构 + 算法

函数式编程面向对象编程面向过程编程

面向对象编程将数据和操作数据的相关方法封装到对象中,组织代码和数据的方式更加接近人的思维,从而大大提高了编程的效率。

什么是对象

对象是内存中专门用来存储数据的一块区域

对象可以存储各种数据(数字、布尔、函数、类)对象的组成成分 对象的标识:ID 对象的类型:type 对象的值:value

面向过程(top-down languages) 面向过程就是当我们实现一个功能的时候,根据逻辑一步一步的完成。 生活中的例子 例如:做西红柿鸡蛋

把西红柿画十字用开水泡将鸡蛋打在碗里并放盐切小葱先炒鸡蛋后炒西红柿 缺点: 只能适用这一个功能,可修改性差,如果编写其他功能恐怕要重新写 优点: 符合人类的思维,编写简单

面向对象 面向对象的编程语言更加关注的是对象,而不是过程,是利用‘类’和‘对象’来创作各种模型对真实世界的描述 例如说鸟,鸟有羽毛,可以飞,可以发出声音等特性

面向对象的编程思想,将所有的功能统一保存到对应的对象中,要使用该功能只要找到相应的对象即可。

如果我们把对象比喻成月饼,那么类就是制作月饼的模具。简单来说类相当于一个设计图纸,我们根据类来创建对象。 创建一个最简单的类

# class 类名([父类]): # 代码块,类的命名为大驼峰命名法(第一个单词字母大写) # 最简单的类 class TestClass(): pass print(TestClass) # 结果为: # <class '__main__.TestClass'> # 使用TestClass创建一个对象 test = TestClass() # 使用类来创建对象,和函数类似 print(test, type(test)) # <__main__.TestClass object at 0x00000285D666BA48> <class '__main__.TestClass'> # isinstance()用来检测一个对象是否是一个类的实例 res = isinstance(test, TestClass) print(res) # True

类创建对象的流程:

创建一个变量test在内存中创建一个新对象(含有ID,type,value)将对象的id赋值给变量

类其实是一个对象,类其实就是用来创建对象的对象。

# 证明类也是一种对象 class TestClass(): pass print(TestClass) # <class '__main__.TestClass'> print(id(TestClass))# 2773834669272 print(type(TestClass))# <class 'type'> print(isinstance(TestClass, type))# True 变量ValueTestClass<class ‘main.TestClass’>id2773834669272type<class ‘type’>valuepass

self

class American_soldier: def __init__(self, name, arms, attack, life_value=100, speed=1): # 构造函数 # 在实例化是做一些类的初始化的工作 self.name = name # 实例变量(静态属性),作用域就是实例本身 self.arms = arms self.attack = attack self.life_value = life_value self.speed = speed def shot(self): # 类的方法(功能,动态属性) print('shooting...') def change(self): print('i am change') def run(self): print('runing...') A1 = American_soldier('youli', '兵', '对地') # 实例化(初始化一个类) A1.change() # American_soldier.change(r1) 函数和类一样,不调用不执行,但是在内存中存在 def testdef(): pass class TestClass: pass print(TestClass, testdef) # <class '__main__.TestClass'> <function testdef at 0x000001E3EBC49288> 我们创建对象,根据类的要求传递参数A1 = American_soldier(‘A1’, ‘兵’, ‘对地’) ,实际上传递为 A1 = American_soldier(A1,‘youli’, ‘兵’, ‘对地’) 将变量名传递进去,相当于A1.name = ‘youli’, A1.arms = ‘兵’调用方法时A1.run() 为:American_soldier.run(A1) 类变量和实例变量的区别 class TestClass: noble = 1 def __init__(self, name, noble): self.name = name self.noble = noble def run(self): print('%s runing' %self.name) test1 = TestClass('test1', 12) test2 = TestClass('test2', 22) # 可以在类外进行赋值 test1.name = 'test_new' # 增加新属性 test1.age = 18 test1.tel = 1191 test1.run() # 类方法 print(TestClass.noble) # 类变量存在类里 print(test1.name, test1.noble) # 修改实例变量后,如果类变量和实例变量都有则以实例变量为主 print(test1.name, test1.noble) # 查看新实例化 print(test1.age) print(test1.tel) # 删除属性 del test1.tel # print(test1.tel) # 在实例中改变类属性,只改变实例中的 类属性变量,不改变其他变量

析构函数

class School: def __init__(self): print('我起床了') def __del__(self): print('我上学去了') def eat(self): print('我吃饭了') p=School() p.eat() # 析构函数,在实例释放或者销毁的时候执行的函数, # 通常用为扫尾工作,比如关掉临时文件,打开的数据库连接

私有属性,私有方法

class Student(): def __init__(self, name, age, hobby): self.name = name self.age = age self.__hobby = hobby def run(): print('runing') def show_hobby(self): print('name: %s hobby: %s'%(self.name, self.__hobby)) def __go_to_bar(self): print('go to bar') student1 = Student('Li', 18, 'LOL') # 无法查看 # print(student1.hobby) print(student1.show_hobby()) # 无法查看 # student1.__go_to_bar()

继承

class Boss_One: def __init__(self, name ,grade): self.name = name self.grade = grade def run(self): print('%s is runing'% self.name) def attack(self): print('%s has 10 attacks'% self.name) def jump(self): print('%s is jump'% self.name) class Boss_Ten(Boss_One): def run(self): # 将父类的写上去 Boss_One.run(self) # 重写父类方法 print('runing faster') b1 = Boss_Ten('slim', 1) b1.run()

在父类的基础上添加新的属性

# class Boss_One: # 经典类 class Boss_One(object): # 新式类 def __init__(self, name ,grade): self.name = name self.grade = grade def run(self): print('%s is runing'% self.name) def attack(self): print('%s has 10 attacks'% self.name) def jump(self): print('%s is jump'% self.name) class Boss_Ten(Boss_One): # 在父类的基础上添加新的属性 def __init__(self, name, age, horns): # 方法一 # Boss_One.__init__(self, name, age) # 方法二 super(Boss_Ten, self).__init__(name, age) #(新式类) # 优点在于多继承 self.horns = horns def run(self): # 将父类的写上去 Boss_One.run(self) # 重写父类方法 print('runing faster') b1 = Boss_Ten('slim', 1,'True') b1.run() # 在执行多继承时,从左往右继承,如果出现的方法则不会覆盖更新 class Left(object): def __init__(self, name): self.name = name def run(self): print('left runing') class Right(object): def __init__(self, tall): self.tall = tall def run(self): print('right runing') class Mid(Left, Right): pass m1 = Mid('Row') m1.run() # left runing

深度优先和广度优先

class A(object): def __init__(self): print('A') class B(A): pass # def __init__(self): # print('B') class C(A): pass # def __init__(self): # print('C') class D(B, C): pass obj = D() # 广度优先,先找B,然后找C,两个都没有找A # python 是深度优先

静态方法

# 静态方法 # 只是名义上归类管理,实际上在静态方法里放访问不了类或实例中的任何属性 class People(object): def __init__(self, name): self.name = name @staticmethod # 这里处理实际上和类没有什么关系了,唯一的是在类里使用,就一个单纯的函数 def eat(self): print(' %s is eating %s' %(self.name,'noodles')) d = People('Lihua') d.eat() # 报错 # TypeError: eat() missing 1 required positional argument: 'food' # 去掉food,用noodles代替,去掉d.eat('noodles')中的noodles # 报错 # TypeError: eat() missing 1 required positional argument: 'self' # 但是在类中传递参数是自动传递的

类方法

class People(object): n = 'Li' def __init__(self, name): self.name = name @classmethod def eat(self): print(' %s is eating %s' %(self.n,'noodles')) d = People('Lihua') d.eat() # 报错 # AttributeError: type object 'People' has no attribute 'name' # 输入类变量 # Li is eating noodles # 类方法只能访问类变量,不能访问实例变量

属性方法

class People(object): def __init__(self, name): self.name = name self.__food = None @property def eat(self): print(' %s is eating %s' %(self.name,self.__food)) d = People('Lihua') d.eat() # 报错 # TypeError: 'NoneType' object is not callable # 去掉d.eat()的() # 结果 # Lihua is eating noodles # 属性方法 # 把一个方法变成一个静态属性

属性方法传递参数

class People(object): def __init__(self, name): self.name = name self.__food = None @property def eat(self): print(' %s is eating %s' %(self.name,self.__food)) @eat.setter def eat(self, food): print('set to food:', food) self.__food = food d = People('Lihua') d.eat d.eat = 'baozi' d.eat # Lihua is eating None # set to food: baozi # Lihua is eating baozi

删除属性方法

class People(object): def __init__(self, name): self.name = name self.__food = None @property def eat(self): print(' %s is eating %s' %(self.name,self.__food)) @eat.setter def eat(self, food): print('set to food:', food) self.__food = food @eat.deleter def eat(self): del self.__food print('删除完毕') d = People('Lihua') d.eat d.eat = 'baozi' d.eat del d.eat d.eat # Lihua is eating None # set to food: baozi # Lihua is eating baozi # 删除完毕 # AttributeError: 'People' object has no attribute '_People__food'

类的特殊成员方法

# __doc__ 表示类的描述信息 class Person(object): """描述人的相关信息""" print(Person.__doc__) # __dict__ class Person(object): sex = 'M' def __init__(self, name, count): self.name = name self.count = count def func(self, *args, **kwargs): print('func') p = Person('li',12) print(Person.__dict__) # 打印类里的所有属性,不包括实例属性 print('\n') print(p.__dict__) # 打印实例属性,不包括类属性 # {'__module__': '__main__', 'sex': 'M', '__init__': <function Person.__init__ at 0x0000020D787543A8>, 'func': <function Person.func at 0x0000020D78754A68>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} # {'name': 'li', 'count': 12} # __str__ 如果一个类中定义了__str__方法,那么在打印对象时,默认输出改方法的返回值。 class Person(object): def __init__(self, name): self.name = name def run(self): print('%s is runing' % self.name) def __str__(self): return "<--->" p = Person('li') print(p) # 创建类的第二种方式 def say(self): print('%s hello' %self.name) def __init__(self, name, age): self.name = name self.age = age Person = type('Person', (object,), {'say_one':say, '__init__':__init__}) p = Person('li', 15) p.say_one() print(type(Person))

反射

# 反射 # 通过字符串反映或修改程序运行时的状态、属性、方法 # 反射 # 通过字符串反映或修改程序运行时的状态、属性、方法 def say(self): print('%s is say hello'% self.name) class Person(object): def __init__(self, name): self.name = name def run(self): print("%s is runing"%self.name) p = Person('li') choice = input(">>:").strip() # 当用户输入需求时,不知道我们调用的类是什么, # 他们输入的只是字符串,反射就是为了实现更好的交互 print(hasattr(p, choice)) # print(hasattr(p, choice)) #判断一个对象p里是否有 对应的choice字符串choice的方法、属性 # >>:name # True # ----------------------------------------------------- # getattr()根据字符串去获取p对象里的对应的方法的内存地址 print(getattr(p, choice)) # 实现用户输入字符串达到调取功能 if hasattr(p, choice): attr = getattr(p, choice) attr() # ----------------------------------------------------- if hasattr(p, choice): attr = getattr(p, choice) attr() else: # 添加新的属性,如果客户输入一个没有的属性则返回zero setattr(p, choice, 'zoro') print(getattr(p, choice)) def say(self): print('%s is say hello'% self.name) class Person(object): def __init__(self, name): self.name = name def run(self): print("%s is runing"%self.name) p = Person('li') choice = input(">>:").strip() if hasattr(p, choice): attr = getattr(p, choice) attr() else: # 动态装一个方法 setattr(p, choice, say) func = getattr(p, choice) func(p) def say(self): print('%s is say hello'% self.name) class Person(object): def __init__(self, name): self.name = name def run(self): print("%s is runing"%self.name) p = Person('li') choice = input(">>:").strip() if hasattr(p, choice): delattr(p, choice) # 删除属性 attr = getattr(p, choice) setattr(p, choice, 'runing') #修改属性 else: # 动态装一个方法 setattr(p, choice, say) func = getattr(p, choice) func(p) print(p.name)
最新回复(0)