对象
在python中一切皆是对象,所以想要理解python必须了解在python中对象、实例、类、元类、type等概念,我认为只有自己理解了这写概念,才能更好的理解python中的面向对象是什么样的,这里把搜集的资料和自己的理解写下,作为面向对象的前篇。
我们可以把我们所处的真实空间,和计算机的内存空间做一下类比(突然有种黑客帝国的既视感)。在我们的世界里有具体和抽象的分别,举个例子家里有只小猫叫逗逗,那逗逗这个实体就是对象,猫这个概念就是类。
我们通过描述属性(特征)和行为来描述一个对象。
逗逗1岁,毛色是橘色,体重8斤,这些都是它的属性,是静态的。
逗逗会跑,会叫,会撒娇,这些是它的行为,是动态的。
在python中,一个对象的特征也称为属性(attribute)。它所具有的行为也称为方法(method)
对象=属性(静态)+方法(动态)
对象的属性
python使用对象模型来存储数据。构造任何类型的值都是一个对象。
所有Python对象都拥有三个属性:身份、类型、值
身份:每个对象都有一个唯一的身份标识,任何对象的身份可以使用内建函数id()来得到
类型:对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则。可以使用 type()函数查看python对象的类型。type()返回的是对象而不是简单的字符串。
值:对象表示的数据。
对象的方法
方法就是可以对对象做的操作,它们是一些代码块。可以调用这些代码来完成某个工作。方法其实就是在对象中的函数。函数能做到的,方法都能做到,包括传递参数和返回值。
类
在这里主要讨论两点:
(1)相对于对象来说类的定义是什么
(2)相对于类来说它为什么是对象
第一部分
我们先来回答第一个问题,相对于对象来说,类是用来描述具体相同的属性和方法的对象的集合。类定义了该集合中每个对象所共有的属性和方法。
我们在这里学习一下如何构造一个类,并初始化对象并实例化,最后根据代码来介绍里面重要的概念。
建立对象的过程
首先我们创建类对象,再给它一个方法:(类对象概念后文解释)
class Cat:
def sleep(self):
print("This cat will sleep %s houres everyday."%self.time)
现在我们想实例化对象,并给对象添加属性。
实例化语法:
instance_name = class_name()
class Cat:
def sleep(self):
print("This cat will sleep %s houres everyday."%self.time)
doudou=Cat() #实例化
doudou.name="doudou"
doudou.time="8"
doudou.color="orange"
doudou.sleep()
运行结果为:
This cat will sleep 8 houres everyday.
之前有接触过面向对象的同学可能会疑惑,一般是先初始化对象,再实例化,这里的类并没有初始化实例变量name,time和color为什么这里可以运行,其实我们在实例化之后添加实例变量时默认运行了类的构造函数__init__了。在这里默认运行了:
def __init__(self,name,time,color):
self.name=name
self.time=time
self.color=color
这是因为python作为动态语言是可以再定义了类之后,修改其实例变量的。(详见后文属性绑定)
(这里的实例变量和类变量的概念在后文解释。)
而常规的初始化方法是在建立类对象时,设置对象的属性,代码如下:
class Cat(object):
def __init__(self,name,time,color):
self.name=name
self.time=time
self.color=color
def sleep(self):
print("%s will sleep %s houres everyday."%(self.name,self.time))
doudou=Cat("doudou","8","orange")
doudou.sleep()
运行结果为:
doudou will sleep 8 houres everyday.
构造函数与self
构造函数的语法:
def __init__(self,实例变量1,实例变量2,...,实例变量n):
self.实例变量1=a(初始值,没有具体初始值可以直接写实例变量1)
...
self.实例变量n=n(初始值,没有具体初始值可以直接写实例变量n)
Python类实例有两个特殊之处:
__init__在实例化时执行
Python实例调用方法时,会将实例对象作为第一个参数传递给self。
一些重要的概念
类对象:
类定义完成后,会在当前作用域中定义一个以类名为名字,指向类对象的名字。
类对象支持的操作:
总的来说,类对象仅支持两个操作:
1.实例化;使用instance_name = class_name()的方式实例化,实例化操作创建该类的实例。
2.属性引用;使用class_name.attr_name的方式引用类属性。
实例对象:
实例对象是类对象实例化的产物,实例对象仅支持一个操作:
属性引用;与类对象属性引用的方式相同,使用instance_name.attr_name的方式。
类变量与实例变量:
更贴切的说法是类的属性和实例的属性,实例变量是对于每个实例都独有的数据,而类变量是该类所有实例共享的属性和方法。
属性绑定:
不管是类对象还是实例对象,属性都是依托对象而存在的。
我们说的属性绑定,首先需要一个可变对象,才能执行绑定操作,使用
objname.attr = attr_value的方式,为对象objname绑定属性attr。
这分两种情况:
(1)若属性attr已经存在,绑定操作会将属性名指向新的对象;
(2)若不存在,则为该对象添加新的属性,后面就可以引用新增属性。
类属性绑定:
Python作为动态语言,类对象和实例对象都可以在运行时绑定任意属性。因此,类属性的绑定发生在两个地方:
(1)类定义时;
(2)运行时任意阶段。
class Dog:
kind = 'canine'
Dog.country = 'China'
print(Dog.kind, ' - ', Dog.country)
# output: canine - China
del Dog.kind
print(Dog.kind, ' - ', Dog.country)
# AttributeError: type object 'Dog' has no attribute 'kind'
在类定义中,类属性的绑定并没有使用objname.attr = attr_value的方式,这是一个特例,其实是等同于后面使用类名绑定属性的方式。
因为是动态语言,所以可以在运行时增加属性,删除属性。
实例属性绑定:
与类属性绑定相同,实例属性绑定也发生在两个地方:
(1)类定义时;
(2)运行时任意阶段。
示例代码见创建对象的过程那一节中实例化部分。
第二部分
这一部分回答第二个问题,Python中一切皆对象,类也是对象 。在这里主要讨论三个概念,type、object、class。
Python: 一切为对象
>>> a = 1
>>> type(a)
<class'int'>
>>> type(int)
<class'type'>
type => int => 1
type => class => obj
type是个类,生成的类也是对象,生成的实例是对象
>>>class Student:
>>> pass
>>>
>>>stu = Student()
>>>type(stu)
__main__.Student
>>>Student.__base__
object
Student的父类是obj
>>>class MyStudent(Student):
>>> pass
>>>
>>>MyStudent.__base__ #__base__是找到当前类的
__main__.Student
MyStudent继承Student
MyStudent的父类是Student
object是最顶层的父类
type是个类,同时type也是个对象
>>> type.__base__
object
>>> type(object)
type
>>> object.__bases__
()
object是type的实例
type继承object
我们可以把这些分为3类:
第一类:type自成一类,type是自己的对象(可以实例化自己),type可以把所有变成他的对象
第二类:list、str、Student…类会继承object,list、str、Student…是类,同时也是type的对象。object是所有的基类(一切都继承object)
第三类:生成的对象