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中,上述两种定义方式全都是新式类
View Code

 

属性:

类是用来描述一类事物,类的对象指的是这一类事物中的一个个体

是事物就要有属性,属性分为:

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__# 实例对应的类(仅新式类中)

类的特殊属性(了解即可)
python为类内置的特殊属性

练习:编写一个学生类,产生一堆学生对象,要求有一个计数器(属性),统计总共实例了多少个对象 

class Student(object):
    num = 0
    def __init__(self):
        Student.num += 1

s1 = Student()
s2 = Student()
s3 = Student()
print(Student.num)
View Code

 

posted @ 2019-09-18 09:22  Mr-谢  阅读(204)  评论(0)    收藏  举报