1.什么是面向对象?
在大学学习c#的时候接触面向对象,知道好像有什么方法,属性,人狗大战啥的。但是都忘记了,也不知道面向对象到底是个啥! 在python中一切都是对象,linux中一切都是文件(突然想起来了) 什么是class?什么是对象?什么是属性? 人狗大战走起!!!
class People:
a =1000 #静态变量,是所有对象共同使用的值,通过类名来调用 def __init__(self, name, hp, ad, sex): #等价于People(),实例化这个类,主动调用。谁在实例化这个类,self这个参数就属于谁
#self指向了一块内存地址,里面存的是字典,用于接收传递进来的参数,然后自动返回给调用者
#调用__init__,自动传入了self函数,其他参数都是按照顺序传递进来的,并且添加到这个字典中
#执行__init__函数
#返给给调用者self self.name = name #实例变量 对象属性 self.hp = hp self.ad = ad self.sex = sex def fight(self, dog): #动态变量 对象方法 dog.hp -= self.ad print("%s打了%s,%s掉了%s血" % (self.name, dog.name, dog.name, self.ad)) class Dog(): def __init__(self, name, hp, ad, sex): self.name = name self.hp = hp self.ad = ad self.sex = sex def bite(self, people): people.hp -= self.ad print("%s咬了%s,%s掉了%s血" % (self.name, people.name, people.name, self.ad)) jordan = People("alex", 300, 20, '男') #创建一个对象也是在创建一个实例 james = Dog('hei', 400, 10, '女') jordan.fight(james) #对象名调用类里面的函数,并将调用者的名字和参数传递到方法里面,jordan=self
jordan.hp = 20000 #通过对象名添加属性
del jordan.sex #通过对象名删除属性 print(james.__dict__)
1.class:用于定义一个具有相同方法和属性的一类事物
2.对象:根据一个模板(class)刻画出来的一个实体,具有模板里面的一切方法和属性
3.不同的对象有不同的属性,比如我们都有手,但是我的手比你的好看,这就是属性
查看类当中的所有变量:print(类名.__dict__)
查看对象当中的指定变量:
方法一:print(对象.__dict__['变量'])
方法二:print(对象.变量) ---常用
面向对象编程:把属性和动作封装到一个类型当中,就是面向对象编程(通过Dog类生成好多具有Dog类属性和方法的狗)
2.类的加载顺序
class A: def __init__(self): #初始化函数是类的被实例化的时候执行 print('执行我了') def func(self): print('1111111') def func(self): print('2222222',A.country) country = 'China' country = 'English' a = A() #执行初始化函数 a.func() #按照类的加载顺序来看,内存中先是开辟一个__init__的空间,然后开辟函数func的空间,看见第二个函数func的名字和第一个相同,就将第一个的执行断掉,将func指向第二个内存地址 #然后接受两个country,所以打印出来的就是初始化函数的print(),第二个func函数,其中A.country的值是第二个country的值
注意类的加载顺序如下:
1.类内部的一个缩进的所有代码块都是在py文件从上到下解释的时候就已经被执行了
2.类中的代码永远是从上到下依次执行的
3.类的对象的命名空间
class B: l = [0] #可变变量 def __init__(self,name): #类在实例化是被执行 self.name = name b1 = B('科比') b2 = B('jordan') print(B.l) print(b1.l) print(b2.l) b1.l[0] += 1 #相当于使用类B里面的静态变量可变的l,并且为l的第0个元素赋值为1,所以所又使用类B实例化的对象都会随之改变 print(b2.l[0]) #是对象b2调用类里面的可变的数据变量l,再上一步中b1已经修改过了此变量,所以结果为1 b1.l = [123] #相当于在b1的空间里面新定义了一个l,并且赋值为1123,和类B没有关系,和使用类B进行实例化的对象也没有关系 print(b2.l) #所以b2.l还是为1
1.类中的内容和对象中的内容是分别存储的,是存储在两个不同的内存空间
2.类是全部加载完整个类之后,类名才指向类给开辟的内存地址
而函数不是,函数从Python解释器解释到定义函数之后,就将函数名和参数一起分配一个内存地址了,但是函数内部代码在函数被调用的时候才会分配内存地址
3.在对象的内存空间的上方有一个指向类的内存地址的指针,叫类指针,是一个变量
4.对象去类空间中找名字:通常是在自己的空间中没有这个名字,通过类指针找到类的内存地址中去找变量
注意:在操作类里面的静态变量的时候,应该尽量使用类名操作而不是变量名
对于可变的数据类型,最好使用对象名来进行调用
对于不可变的数据类型最好使用类名来进行调用
结论:只要是一个[对象.名字]直接赋值,那么就是在这个对象的空间内创建了一个新的属性
只要是对一个可变的数据类型内部进行改变,那么会改变所有的通过该类进行实例化的属性
4.组合:一个类的对象是另一个类的属性
class Student: def __init__(self,name,num,course): self.name = name self.num = num self.course = course class Course: def __init__(self,name,price,period): self.name = name self.price = price self.period = period python = Course('python',20000,'6 months') s1 = Student('kobe',10086,python) #s1中的python是使用Course实例化出来的对象,s1.course.(name|price|period) 是s1这个学生的课程具有了name,price,period属性 s2 = Student('james',10010,python) s3 = Student('jordan',10011,python) # print(s1.name) # print(s1.num) # print(s1.course.period) print(s1.__dict__) #打印这个对象的变量,可以看到course里面存放的是python对象的内存地址(一个类的对象可以传给另一个类的属性)