python开发基础----类与对象
类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念
对象:就是基于类而创建的一个具体的事物(具体存在的)也是特征和动作整合到一起
def dog(name,age,types): def init(): dogs = { "name":name, "age":age, "types":types, "jiao":jiao, "chishi":chishi } return dogs def jiao(self): print("一条狗%s,正在叫汪汪汪!" % self["name"]) def chishi(self): print("一条狗%s,正在吃屎!" % self["types"]) return init() d1 = dog("alex",2,"中华田园犬") d2 = dog("qaz",1,"藏獒") d1["jiao"](d1) d2["chishi"](d2)
什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例)。类即类别、种类,是面向对象设计最重要的概念。
什么是对象:睁开眼,你看到的一切的事物都是一个个对象,可以把对象理解为一个具体的事物(事物即数据和动作的结合体)
类和对象的关系:对象都是由类产生的,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体
什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象)
那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看
在现实世界中:先有对象,再有类
世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念
也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在
在程序中:务必保证先定义类,后产生对象
这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类
不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象
PS:
1. 站的角度不同,定义出的类是截然不同的,详见面向对象实战之需求分析
2. 现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类......
3. 有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类
经典类和新式类(注意,定义类时,类名首字母大写,函数属性名 动词_名词)
大前提: 1、只有在python2中才分新式类和经典类,python3同一用新式类 2、新式类和经典类声明的最大不同在于,新式类必须继承至少一个父类 3、所有类不管是否显示声明父类,都有一个默认继承object父类 python2中区分: 经典类: class 类名: pass 新式类: class 类名(父类): pass python3中,上述两种定义方式全都是新式类
属性:
类是用来描述一类事物,类的对象指的是这一类事物中的一个个体
是事物就要有属性,属性分为:
1:数据属性:就是变量
2:函数属性:就是函数,在面向对象里通常称之为方法
注意:类和对象均用点来访问自己的属性
类的属性:
数据属性即变量,类的定义与函数又及其类似,其实可以用函数的作用域来理解类的属性调用
1. 类的数据属性是所有对象共享的,id都是一样
2. 类的函数属性是绑定给对象用的
实例化
类实例化的过程本质上就是执行了类.__init__的过程, 这个函数内部只是为实例本身即self设定了一堆数据(变量),所以实例只有数据属性 self 就是实例化对象本身
强调: 1、该方法内可以有任意的python代码 2、一定不能有返回值,因为返回值是None
实例(对象)的属性字典(__dict__)里只有数据属性,并不包含函数属性,函数属性只属于类的属性字典
1、实例只有数据属性(实例的函数属性严格来说是类的函数属性)
2、del实例/对象,只是回收了实例的数据属性,函数属性是属于类的,是不会回收
访问数据属性和函数属性:在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
1、实例化就是类名(),然后返回的结果是一个对象,加上括号是不是跟函数运行很像,函数运行完了有返回值,是不是很像,没错,就是一样的
2、函数有作用域的概念,其实类也有作用域的概念,二者一样
3、可以把class当做最外层的函数,是一个作用域
4、实例化会自动触发__init__函数的运行,最后返回一个值即实例,我们要找的实例属性就存放在__init__函数的局部作用域里
5、类有类的属性字典,就是类的作用域,实例有实例的属性字典,即实例的作用域
6、综上,一个点代表一层作用域,obj.x先从自己的作用域找,自己找不到去外层的类的字典中找,都找不到,就报错
7、在类中没有使用点的调用,代表调用全局变量(在类中调用静态变量可以使用 类名.属性名 )
country = "中国------------------------------" class Chinese: country = "中国" def __init__(self,name): self.name = name print("---->",country) print("---->",Chinese.country) p1 = Chinese("alex") 结果: ----> 中国------------------------------ ----> 中国
查看类属性:有两种方式查看
1、dir(类名):查出的是一个名字列表
2、类名.__dict__:查出的是一个字典,key为属性名,value为属性值(类名.属性,本质是就是在调用 类名.__dict__["属性"])
类属性又称静态变量,或者静态数据。这些数据是与它们所属的类对象绑定的,不依赖于任何类实例
在java或c++中,这种类型的数据相当于在一个变量声明前加上static关键字
class ChinesePeople: country = "China" #静态变量 def __init__(self,name): self.name = name def play_ball(self,ball): #函数属性名 动词_名词 print('%s 正在打 %s' %(self.name,ball)) def say_word(self,word): print('%s 说 %s' % (self.name,word)) #查看类数据属性 print(ChinesePeople.country) #修改类数据属性 ChinesePeople.country='CHINA' print(ChinesePeople.country) #删除类数据属性 del ChinesePeople.country #增加类数据属性 ChinesePeople.country='China' ChinesePeople.location='Asia' print(ChinesePeople.__dict__) #添加类函数属性 p1 = ChinesePeople('alex') def eat(self,food): print('%s 吃 %s'%(self.name,food)) ChinesePeople.eat = eat p1.eat('屎') #覆盖之前类函数属性 def say_word(self): print('text') ChinesePeople.say_word = say_word p1.say_word() print("----------" * 10) #查看实例的数据属性 print(p1.name) #修改实例的数据属性 p1.name = 'qaz' print(p1.name) #添加实例的数据属性 p1.age = 19 print(p1.__dict__) #删除数据属性 del p1.age print(p1.__dict__)
class Chinese: country = "中国" l = ['a','b'] def __init__(self): pass p1 = Chinese() print(p1.l) p1.l.append("c") #这样子给列表添加元素,是给类的 l 属性添加了 c 元素 print(p1.__dict__) print(Chinese.l) p1.l = [1,2,3] #这种是实例新增属性 print(p1.__dict__) 结果: ['a', 'b'] {} ['a', 'b', 'c'] {'l': [1, 2, 3]}
python内置的特殊属性
#python为类内置的特殊属性 类名.__name__# 类的名字(字符串) 类名.__doc__# 类的文档字符串 类名.__base__# 类的第一个父类(在讲继承时会讲) 类名.__bases__# 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__# 类的字典属性 类名.__module__# 类定义所在的模块 类名.__class__# 实例对应的类(仅新式类中) 类的特殊属性(了解即可)
练习:编写一个学生类,产生一堆学生对象,要求有一个计数器(属性),统计总共实例了多少个对象
class Student(object): num = 0 def __init__(self): Student.num += 1 s1 = Student() s2 = Student() s3 = Student() print(Student.num)
浙公网安备 33010602011771号