目录
一、面向对象编程
在研究对象时主要考虑对象的属性和行为。通常将属性及其行为相同的或相似的对象归为一类(求同存异)。类可以看作是一类对象的抽象,代表此类对象所具有的共同属性和行为。Python是一门面向对象的程序设计,程序的基本组成是类。程序在运行时由类生成对象,对象之间通过发送消息进行通信,进而完成一系列的操作。对象是程序的核心。面向对象程序设计的核心是对象。面向对象中涉及的主要概念有抽象、封装、继承和多态。抽象是对一类具体对象的抽象,得到他们共有的属性和行为,形成类,类就是他们的抽象。封装是有清楚的边界,所有对象的内部信息被限定在这个边界内,接口是对象向外界提供的方法,外界可以通过这些方法与对象进行交互。由于封装的特性禁止了外界对象直接操作类中的数据使得模块与模块之间只能通过严格控制的接口进行交互,这使得模块之间的耦合度大大降低,从而保证了模块具有很好的独立性,使得程序的维护和修改变的十分的容易。继承从某种程度上来说是反抽象或者说是更加具体的一种行为,他为类的重用提供了方便。多态是一个程序中同名的不同方法共存的情况,比如“启动”是所有交通工具的行驶的充要条件,但是不同的交通工具启动的方法也不尽相同。此时,我们可以定义“汽车启动”“轮船启动”,这些名字也都不一样,太麻烦了。而多态就可以帮助我们解决这个问题,只起一个名字“启动”,这样一来通过不同交通工具就都可以相应他们自己“启动”的方法了。Python中的类型其实不仅仅包括数据本身的格式和大小,还包括数据的方法,而类也是一种类型。他应该也能向integer一样进行运算,只不过,类的对象需要自己去定义他的运算(方法)。简单说,类是对一类对象的抽象,是对象的模板,而对象是这个类的具体实例。
二、类及其定义
类是对一类对象的抽象,是对象的模板,而对象是这个类的具体实例。在另一方面,类也是一种用户自己数据类型,通过定义自己的类,可以实例化类的对象(定义自己的数据类型)。
//类的定义语法
class Student(object):
"""定义了一个Student类属性,具有name, sex, age等属性"""
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
student1 = Student("jack", 'male', 10)
print(student1)
print(student1.name, student1.sex, student1.age)
print(student1.__doc__)
//输出
<__main__.Student object at 0x00000276D5B4F0B8>
jack male 10
定义了一个Student类属性,具有name, sex, age等属性
class Student(object):
"""定义了一个Student类属性,具有name, sex, age等属性"""
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def student_print(self):
print(self.name, self.sex, self.age)
student1 = Student("jack", 'male', 10)
print(student1)
student1.student_print()
print(student1.__doc__)
/************************输出**********************/
<__main__.Student object at 0x00000200D758F0B8>
jack male 10
定义了一个Student类属性,具有name, sex, age等属性
class Student(object):
"""定义了一个Student类属性,具有name, sex, age等属性"""
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def student_print(self):
print(self.name, self.sex, self.age)
student1 = Student("jack", 'male', 10)
student1.id = 20181220
student1.student_print()
student2 = Student("曹亚磊", 'male', 20)
student2.student_print()
print(student1.id)
print(student2.id)
/**************************输出*********************/
jack male 10
曹亚磊 male 20
20181220
Traceback (most recent call last):
File "E:/space/Python/PycharmPython/classTemp.py", line 18, in <module>
print(student2.id)
AttributeError: 'Student' object has no attribute 'id'
总结:
类是创建实例的模板,而实例是一个一个具体的对象,各个实例拥有的数据都相互独立,互不影响。
方法就是与实例绑定的函数,和不同函数不同,方法可以直接实例的数据。
self:每一个类的方法的第一个参数都是self,该self是一个指针,指向当前对象。
通过实例调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
Python是一门动态语言,和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然他们都是同一个类的不同实例,但拥有的变量名称都可能不同。
三、类的属性与方法
类的属性分类方法有两种:公有属性与私有属性(前面是否有双下划线__)、类属性和实例属性(属性是否定义在方法内部)
class Student(object):
"""定义了一个Student类属性,具有name, sex, age等属性"""
# address、__grade类属性,其中address为公有属性,__grade为私有属性
# 类属性为所有实例公有
# 私有属性不能在类外访问
address = '上海'
__grade = "八年级"
def __init__(self, name, sex, age, teacher = '董老师'):
# name、sex、age、__teacher为对象属性,其中前三个是公有属性,最后一个是私有属性
# 对象属性由单个实例所有
# 私有属性不能在类外访问
self.name = name
self.sex = sex
self.age = age
self.__teacher = teacher
def student_print(self):
print(self.name, self.sex, self.age, self.__teacher)
student1 = Student("张同学", 'male', 10)
student1.id = 20181220
student1.student_print()
student2 = Student("曹同学", 'male', 20)
student2.student_print()
print(student1.id)
print(student2.address, student1.address)
"""*************************输出***************************"""
张同学 male 10 董老师
曹同学 male 20 董老师
20181220
上海 上海
四、实例方法、类方法、静态方法
class MyClass:
# 实例方法
def method(self):
return 'instance method called', self
# 类方法
@classmethod
def classmethod(cls):
return 'class method called', cls
# 静态方法
@staticmethod
def staticmethod():
return 'static method called'
实例方法
MyClass的第一个方法就叫“方法”,它就是一个普通的实例方法,也是在大多数情况下使用的最基本的、最简单的方法。该方法接受一个参数self,它在调用该方法时指向一个MyClass的一个实例。(当然,实例方法可以接受的参数不止一个)。
通过self参数,实例方法可以自由地访问同一对象的属性和其他方法。当涉及到修改对象的状态时,实例方法就非常给力。
类方法
类方法用装饰符@classmethod进行标记。类方法不接受self参数,而是接受一个cls参数。cls参数在调用方法时,指向的是类而不是对象实例。
由于类方法只能访问cls参数,因此它无法修改对象的实例状态——那就需要访问self。但是,类方法仍然可以对应用于类的所有实例的类状态进行修改。
静态方法
静态方法使用一个装饰符@staticmethod标记的方法。
这个方法既不接受self参数,也不接受cls参数(但是,他可以接受任意数量的其他参数)。
因此静态方法既不能修改对象状态,也不能修改类状态。静态方法在它们可以访问的数据方面受到限制,它们主要用于对你的方法进行空间命名。
五、魔法方法
从入门到进阶,一个很重要的点就是Python中的魔法方法,魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。它们经常是两个下划线包围来命名的(比如 __init__/__new__等等),Python的魔法方法是非常强大的。
如果你学习过Java,那你会发现Python中的魔法方法像是Java中的重载,Python中的魔法方法可以理解为:对类中的内置方法的重载,注意这里不是重写。
举个例子,Python中有个比较操作符==用来比较两个变量的大小,而这个操作符是通过内置函数__eq__来实现的,所以我们只需要通过改变这个内置函数代码,就可以改变重新定义这个操作符的行为。
我们定义一个类Word,继承自str类,现需要重新定义该类的操作符==,使这个操作符用来判断两个字符串长度是否相等,而不是通过字母顺序判断两个字符串是否相等。注意该变化只适用于Word类,而不适用于其它类。
再比如,定义一个利用iter()可以调用__iter__()方法,返回一个迭代器。