|
引入面向对象的例子:
# 人狗大战 def Person(name,blood,aggr,sex): person = { 'name':name, 'blood': blood, 'aggr':aggr, 'sex':sex } return person person1 = Person('person1',100,1,'不详') person2 = Person('person2',200,2,'不详') # print(alex,'\n',dog) def Dog(name,blood,aggr,kind): dog = { 'name':name, 'blood':blood, 'aggr':aggr, 'kind':kind } return dog # 人的技能 打 def attack(person,dog): dog['blood']-= person['aggr'] print('%s被打了,掉了%s的血'%(dog['name'], person['aggr'])) # 狗的技能 咬人 def bite(dog, person): person['blood'] -= dog['aggr'] print('%s被咬了,掉了%s的血'%(person['name'], dog['aggr'])) dog1 = Dog('dog1',100,1,'teddy') dog2 = Dog('dog2',200,2,'金毛') bite(dog1,person1) # print(jin,'\n',dog)
利用面向对象编写程序的优点:
代码精简了,方便增加任务,方便修改,人物更加规范
Dog函数和Person函数都是定义了一类事物,直到调用函数,赋了值才真的有了一个实实在在的人或物
代码改进:
def Person(name,blood,aggr,sex): person = { 'name':name, 'blood': blood, 'aggr':aggr, 'sex':sex } def attack(dog): dog['blood'] -= person['aggr'] print('%s被打了,掉了%s的血' % (dog['name'], person['aggr'])) person['attack'] = attack return person def Dog(name,blood,aggr,kind): dog = { 'name':name, 'blood':blood, 'aggr':aggr, 'kind':kind } def bite(person): person['blood'] -= dog['aggr'] print('%s被咬了,掉了%s的血' % (person['name'], dog['aggr'])) dog['bite'] = bite return dog alex = Person('alex',100,1,'不详') jin = Dog('狗剩',100,1,'teddy') print(jin) jin['bite'](alex) alex['attack'](jin)
面向对象编程
类就相当于是个模子,所谓模子就是类,类是抽象的,我能直到有什么属性,有什么技能,但不能直到属性具体的值。而jin、alex就是对象,有具体的值,属性和技能都是根据类规范的。
面向对象的交互
面向过程:核心是过程(流水线思维),过程即解决问题的步骤。
优点:极大的地降低了写代码地复杂度,只要顺着要执行地步骤,堆叠代码即可。
缺点:一套流水线或者流程就是用来解决一个我呢提,代码牵一发而动全身。
应用场景:一旦完成基本很少改变地场景,著名的例子有Linux内核,git,以及Apache HttP Server等。
面向函数
面向对象:面向对象的程序设计的
解决了程序的扩展性
可控性差,无法向面向过程的程序设计流水线式的可以精准预测问题的处理流程与结果
应用场景:适合复杂的编程
python中万物皆对象
比如:dict 类 d={'k':'v'}是实例化的一个对象
自定义类
自定义函数:
def 函数名():pass
自定义类:
class 类名:属性=‘a’
print(类名.属性)
类的作用就是操作属性,查看属性。self类似一个字典,字典中可以存很多东西,self会自动作为字典返回给调用对象。
class Person: #第一步 def __init__(self,*args): # 第二步 print(args) alex = Person('alex',100,1,'不详') #第三步,返回的值alex就是一个对象,调用类型加上括号就是在调用__init__方法
# __表示内置函数 class Person: def __init__(self,*args): # self类似一个字典,字典里可以存很多东西,self会自动作为一个字典返回给调用对象 self.name = args[0] self.hp = args[1] self.aggr = args[2] self.sex = args[3] alex = Person('alex',100,1,'不详') # alex对象,alex和self字典其实是一回事 print(alex) print(alex.name) print(alex.hp) print(alex.sex) ''' <__main__.Person object at 0x000001F984BBD3C8> alex 100 不详 '''
对象 = 类型() 实例化
过程:
类名()可以创造出一个对象,创造了一个self变量
调用__init__方法,类名括号里的参数会在这里被接收
执行__init__方法
返回self
对象能做的事:
查看属性
调用方法
__dict__,对于对象的增删改查
类名能做的事情:
实例化
调用方法,只不过要自己传递self参数
调用类中的属性,也就是调用静态属性
__dict__,类中的字典只能看不能操作
class Person: country = 'China' # 创造了一个只要是这个类就一定有的属性,称为类属性,也称为静态属性 def __init__(self,*args): # 初始化方法,self是对象,是一个必须传的参数,self中只有属性 # ,self就是一个可以存储很多属性的大字典,只不过往字典里添加属性的方式发生了一些变化 print(self.__dict__) self.name = args[0] self.hp = args[1] self.sex = args[2] self.arrg = args[3] print(id(self)) def walk(self,n): # 定义方法,self是必须传的参数一样,可以改,但是习惯性的名字就是self,且必须写在第一个,后面还可以传其他参数,是自由的 print('%s gogogo,go了%s步'%(self.name,n)) alex = Person('狗剩',100,'女',200) # 类名还可以实例化对象 print(alex.name) # 对象可以查看属性 print(id(alex)) # alex和self是同一内存地址 # print(Person.__dict__) Person.walk(alex,5) #调用方法 类名.方法名(对象名) # == alex.walk(5) # 对象可以调用方法,对象.方法名就可以调用方法 print(Person.country) #静态属性,是这个类拥有的,不会随着对象的创建发生改变 # 类名可以查看类中的属性,不需要实例化就可以查看 print(Person.__dict__) #存储的类中的所有的名字 print(Person.__dict__['country']) #可以以字典的形式操作类 print(alex.__dict__) # 存储的是对象中的所有名字 alex.__dict__['name']='二哥' # 以字典的形式更改对象中的名字 print(alex.name) # == alex.name = '狗剩' #一般情况下用这种方法更改对象的属性 print(alex.name) alex.age=83 print(alex.__dict__) # 添加,和字典的操作方法类似,只是在草的过程中key不是一个字符串类型的值而是一个变量 print(alex.name)
练习
练习 class Dog: def __init__(self,*args): self.name = args[0] self.hp = args[1] self.aggr = args[2] self.kind = args[3] def bite(self,person): # person是人的实例化 # 狗咬人,人掉血 person.blood -= self.aggr # person['blood'] -= dog['aggr'] # print('%s被咬了,掉了%s的血' % (person['name'], dog['aggr'])) class Person: def __init__(self,*args): self.name = args[0] self.blood = args[1] self.aggr = args[2] self.sex = args[3] def attack(self,dog): self.blood -= dog.aggr print('%s被攻击了,掉了%s的血' % (dog.name, self.aggr)) jin = Dog('金老板',100,20,'teddy') alex = Person('alex',999,998,'不详') print(jin.name) jin.bite(alex) # ==Dog.bite(ren) print(alex.blood) print(jin.hp)
类能够非常明显的处理一类事物,这些事物都具有相似的属性和功能
当有几个函数,需要反复传入相同的参数的时候,就可以考虑面向对象
这些参数都是对象的属性
class Person: def __init__(self,*args): self.name = args[0] self.age = args[1] self.sex = args[2] def action1(self): print('%s,%s岁,%s,上山去砍柴'%(self.name,self.age,self.sex)) def action2(self): print(self.name,self.age,self.sex,'开车去东北') def action3(self): print(self.name,self.age,self.sex,'最爱大保健') xiaoming = Person('小明','10','男') xiaoming.action1() xiaoming.action2() xiaoming.action3() zhang = Person('老张',90,'男') zhang.action1() zhang.action2() zhang.action3() ''' 小明,10岁,男,上山去砍柴 小明 10 男 开车去东北 小明 10 男 最爱大保健 老张,90岁,男,上山去砍柴 老张 90 男 开车去东北 老张 90 男 最爱大保健 '''
circle属性 半径,两个办法:周长和面积
from math import pi class Circle: def __init__(self,*args): self.r = args[0] def c(self): print(2*self.r*pi) def s(self): print(pi*(self.r)**2) circle = Circle(3) circle.c() circle.s() ''' 18.84955592153876 28.274333882308138 '''
定义类 class
函数:方法、动态属性
变量:类属性、静态属性
__init__方法
初始化方法,每当我们调用类的时候就会自动触发方法,在触发这个方法之前,python帮我们创建了一个对象self,默认传self,在init方法中可以对self 赋值。
self是什么 self拥有的属性都属于对象
在类的内部,self就是一个对象,alex = Person(),alex也是一个对象,是类外的对象,当调用类的时候自然而然就传给了self,所以说self可以更改,alex.walk == Pearson.walk(alex) self就是alex
类中可以定义静态属性、定义方法,方法都有一个必须传的参数self
实例化
对象=类(参数是init方法的参数)
实例,对象:实例和对象是一回事,完全没有区别
对象查看属性:对象.属性名
对象调用方法:对象.方法名(参数)
类的命名空间
类 可以定义两种属性
静态属性
动态属性
class Course: # 静态属性 # language = 'Chinese' language = ['Chinese'] # 动态属性 def __init__(self,teacher,course_name,period,price): self.teacher = teacher self.name = course_name self.period = period self.price = price python = Course('egon','python','six month',20000) linux = Course('oldboy','linux','six month',20000) # python 和linux之间是平行关系,没什么联系 python.language[0] = 'Enlish' print(linux.language) # 输出结果为:English,对于列表而言列表里面的内容改变,不改变列表的内存地址 python.language=['English'] # 重新赋值 print(Course.language) Course.language = 'English' #类可以改变静态变量 print(Course.language) print(python.language,linux.language) python.language = 'Chinese' #能改变自己空间的,不能改变类中的 print(python.language,linux.language) print(Course.language) ''' ['Enlish'] ['Enlish'] English ['English'] English Chinese English English '''
Course.name 报错,因为对象和类之间是单向联系,兑现可以用类的,但是类不能用对象的
类中的静态变量可以被对象和类调用
对于不可变数据类型,类变量最好用类操作,而不要用对象名操作
对于可变数据类型来说,对象名的修改是共享的,重新赋值是独立的
创建一个类,每实例化一个对象就记录下来,最终所有对象都可以共享数据
在类中就是一个独立的命名空间,找到类之后,再没有就不能往上找了
引入一个包时,就相当于类实例化一个对象,所以包会自动帮你调用一个__init__文件
class Person: money = 0 def __init__(self): self.money += 1000 # def work(self): # Person.money += 1000 mother = Person() father = Person() print(mother.money) print(father.money)
将方法和对象绑定在一起,当对象调用方法的时候就是把对象当成self传到方法中。
def func():pass print(func) class Foo: def func(self): print('func') f1 = Foo() print(Foo.func) print(f1.func) # 方法和对象绑定在一起,当对象调用方法的时候就是把对象当成self传到方法中 print(f1)
组合
组合就是一个对象的属性值是另一个类的对象
class Dog: def __init__(self,*args): self.name = args[0] self.hp = args[1] self.aggr = args[2] self.kind = args[3] def bite(self,person): # person是人的实例化 # 狗咬人,人掉血 person.blood -= self.aggr # person['blood'] -= dog['aggr'] # print('%s被咬了,掉了%s的血' % (person['name'], dog['aggr'])) class Person: def __init__(self,*args): self.name = args[0] self.blood = args[1] self.aggr = args[2] self.sex = args[3] self.money = 0 def attack(self,dog): self.blood -= dog.aggr print('%s被攻击了,掉了%s的血' % (dog.name, self.aggr)) def get_weapon(self,weapon): if self.money >=weapon.price: self.money -= weapon.price self.weapon = weapon self.aggr += weapon.aggr else: print('余额不足,请先充值') class Weapon: def __init__(self,name,aggr,njd,price): self.name = name self.aggr = aggr self.njd = njd self.price = price def hand18(self,person): if self.njd > 0: person.hp -= self.aggr * 2 self.njd -= 1 alex = Person('alex',0.5,100,'不详') jin = Dog('金老板',100,0.5,'不详') w = Weapon('打狗棒',100,3,998) alex.money += 1000 alex.get_weapon(w) print(alex.weapon) print(alex.aggr) alex.attack(jin) alex.weapon.hand18(jin) print(jin.hp)
实例:求圆环的周长和面积
from math import pi class Circle: def __init__(self,*args): self.r = args[0] def perimeter(self): return 2*self.r*pi def area(self): return pi*(self.r)**2 class Ring: def __init__(self,outside_r,inside_r): self.outside_c = Circle(outside_r) self.inside_c = Circle(inside_r) def perimeter(self): return self.outside_c.perimeter()+self.inside_c.perimeter() def area(self): return self.outside_c.area()-self.inside_c.area() ring = Ring(20,10) print(ring.area()) print(ring.perimeter())
class Teacher: def __init__(self,name,age,sex,bir): self.name = name self.age = age self.sex = sex self.bir = bir class Bir: def __init__(self,year,month,day): self.year = year self.month = month self.day = day b = Bir(2018,1,16) egg = Teacher('egon',18,'女',b) # 通过Teacher属性可以拿到Bir属性 print(egg.name) print(egg.sex)
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-4-27 01:24
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社