初识类和对象
python中一切皆为对象,类型的本质就是类。
类是抽象的,通俗来说就是我知道有什么属性,有什么技能,但不知道具体的值。
对象是具体的,属性和技能都是根据类规范的。
在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是“类”,对象则是这一类事物中具体的一个。
1、类有两种作用:属性引用和实例化
1.1、属性引用(类名、属性)
class Person: #定义一个人类 role = 'person' #人的角色属性都是人 def walk(self): #人都可以走路,也就是有一个走路方法 print("person is walking...") print(Person.role) #查看人的role属性 print(Person.walk) #引用人的走路方法,注意,这里不是在调用
1.2、实例化
类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例订制自己的特征
class Person: #定义一个人类 role = 'person' #人的角色属性都是人 def __init__(self,name): self.name = name # 每一个角色都有自己的昵称; def walk(self): #人都可以走路,也就是有一个走路方法 print("person is walking...") print(Person.role) #查看人的role属性 print(Person.walk) #引用人的走路方法,注意,这里不是在调用
实例化的过程就是类——>对象的过程
原本我们只有一个Person类,在这个过程中,产生了一个egg对象,有自己具体的名字、攻击力和生命值。
语法:对象名 = 类名(参数)
注:参数是init方法的。
egg = Person('egon') #类名()就等于在执行Person.__init__() #执行完__init__()就会返回一个对象。这个对象类似一个字典,存着属于这个人本身的一些属性和方法。 #你可以偷偷的理解:egg = {'name':'egon','walk':walk}
类名能做的事:
1)实例化
2)调用方法:只不过要自己传递self参数
3)调用类中的属性,也就是调用静态属性
4)__dict__对于类中的名字只能看,不能操作。
5)但是可以直接修改。
补充:
类关键字:class
__init__方法:初始化方法,python帮我们创建了一个对象self,每当我们调用类的时候就会触发这个方法,默认传self,在这个方法里可以对self进行赋值。
self是什么?
self拥有的属性都属于对象,是一个空对象,以字典形式存在。
实例跟对象完全没有区别。
2、对象之间的交互
对象是关于类而实际存在的一个例子,即实例。
对象/实例只有一种作用:属性引用。
对象查看属性:对象.属性名
对象调用方法:对象.方法名(参数)
类名.方法名(对象名,参数)
对象能做的事:
1)查看属性
2)调用方法
3)__dict__对于对象的增删改查操作都可以通过字典的语法进行。
class Dog: def __init__(self,name,blood,aggr,kind): self.name=name self.blood=blood self.aggr=aggr self.kind=kind def bite(self,person): person.blood-=self.aggr print("%s咬了%s,%s掉了%s血"%(self.name,person.name,person.name,self.aggr)) if person.blood<=0: print("%s咬了%s,%s死掉了"%(self.name,person.name,person.name)) class Person: def __init__(self,name,blood,aggr,sex): self.name = name self.blood = blood self.aggr = aggr self.sex = sex def attack(self,dog): dog.blood-=self.aggr if dog.blood <= 0: print("%s打了%s,%s死掉了" % (self.name,dog.name,dog.name)) else: print("%s打了%s,%s掉了%s血" % (self.name, dog.name,dog.name, self.aggr)) alex=Person("二哥",1000,100,"男") jin=Dog("阿花",30,100,"Teddy") jin.bite(alex) alex.attack(jin) print(jin.blood) print(alex.blood)
3、类和对象命名空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法
对象找名字 : 先找自己的 找类的 再找不到就报错
对象修改静态属性的值
对于不可变数据类型来说,类变量最好用类名操作
对于可变数据类型来说,对象名的修改是共享的,重新赋值是独立的
类的数据属性是共享给所有对象的
>>>id(egg.role) 4341594072 >>>id(Person.role) 4341594072
类的动态属性是绑定到所有对象的
>>>egg.attack <bound method Person.attack of <__main__.Person object at 0x101285860>> >>>Person.attack <function Person.attack at 0x10127abf8>
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
class Course: language="Chinese" #静态属性 def __init__(self,teacher,course_name,period,price): self.teacher=teacher self.course_name=course_name self.period=period self.price=price def func(self): pass python = Course('egon','python','6 months',20000) linux = Course('oldboy','linux','6 months',20000) Course.language="Endlish" #可直接修改 # Course.__dict__["language"]="English" #__dict__对于类中的名字只能看,不能直接修改 print(Course.language) #Endlish python.language="Chinese" print(python.language) #Chinese python独有属性 print(Course.language) #Endlish print(python.__dict__) print(linux.__dict__) #{'teacher': 'egon', 'period': '6 months', 'price': 20000, 'course_name': 'python', 'language': 'Chinese'} print(Course.__dict__) #{'teacher': 'oldboy', 'period': '6 months', 'price': 20000, 'course_name': 'linux'}
class Person: money=0 def work(self): Person.money+=1000 mother=Person() #实例化mother father=Person() #实例化father mother.work() #+1000 father.work() #+1000 print(Person.money) #2000
例:创建一个类,每实例化一个对象就计数最终所有的对象共享这个数据
class Foo: count=0 def __init__(self): Foo.count+=1 f1=Foo() #实例化对象 f2=Foo() #实例化对象 print(f1.count) #2 print(f2.count) #2 f3=Foo() #实例化对象 print(f3.count) #3 print(f1.count) #3
4、面向对象的组合
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。(什么有什么的关系)
class Dog: def __init__(self,name,aggr,hp,kind): self.name = name self.aggr = aggr self.hp = hp self.kind = kind def bite(self,person): person.hp -= self.aggr class Person: def __init__(self,name,aggr,hp,sex): self.name = name self.aggr = aggr self.hp = hp self.sex = sex self.money = 0 def attack(self,dog): dog.hp -= 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,500,'teddy') w = Weapon('打狗棒',100,3,998) # alex装备打狗棒 alex.money += 1000 alex.get_weapon(w) print(alex.weapon) print(alex.aggr) alex.attack(jin) print(jin.hp) alex.weapon.hand18(jin) print(jin.hp)
下面看一下计算圆环面积和周长的例子,了解一下面向对象的组合。
from math import pi class Circle: #定义了一个圆形类 def __init__(self,r): self.r = r def area(self): #计算圆面积方法 return self.r**2 * pi def perimeter(self): #计算圆周长方法 return 2*pi*self.r class Ring: #定义了一个圆环类 def __init__(self,outside_r,inside_r): self.outside_c=Circle(outside_r) self.inside_c=Circle(inside_r) def area(self): #计算圆环面积方法 return self.outside_c.area()-self.inside_c.area() def perimeter(self): #计算圆环周长方法 return self.outside_c.perimeter()+self.inside_c.perimeter() ring=Ring(10,2) #实例化一个圆环 print(ring.area()) #计算圆环的面积 print(ring.perimeter()) #计算圆环的周长
用组合的方式建立了类与组合的类之间的关系
关于老师所教课程和生日
class Birthday: def __init__(self,year,month,day): self.year=year self.month=month self.day=day class Course: def __init__(self,course_name,period,price): self.course_name=course_name self.period=period self.price=price class Teacher: def __init__(self,name,age,sex,birthday): self.name=name self.age=age self.sex=sex self.birthday=birthday self.course=Course("python","6 months",19800) ya=Birthday(2018,1,16) yaya=Teacher("egon",18,"女",ya) print(yaya.birthday.year) #2018 print(yaya.birthday.month) #1 print(yaya.course.price) #19800
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好。