Python类
一、理解
类相当于模板,对象是类的实例。
可以把类理解成做饼干的模子,对象就是用模子做出的饼干。
我们定义一个class的时候,我们实际上就定义了一种数据类型,我们定义的数据类型和python自带的数据类型,比如str,list,dict没什么两样
二、定义
class ClassName: 'xxxxx' # 类文档字符串,可通过ClassName.__doc__查看 class_suite # 类体
三、类的实例
定义完成后,并不会真正创建一个实例。这就好比一个汽车的设计图。设计图可以告诉你汽车看上去怎么样,但设计图本身不是一个汽车。你不能开走它,它只能用来建造真正的汽车,而且可以使用它制造很多汽车。那么如何创建实例呢?
ClassName(parameterlist) # ClassName:是必选参数,用于指定类。 # parameterlist:可以选参数,当创建一个类时,没有创建__init__()方法,或者当__init__()方法只有一个self参数时, parameterlist可以省略。 例如: # 创建类 class Geese: """大雁类""" pass # 创建实例 wildGoose = Geese()
判断一个变量是否是某个类型可以用isinstance()判断: isinstance(wildGoose,Geese),返回true
四、魔术(构造)方法
在创建类后,类通常会自动创建一个__init__()方法。该方法是一个特殊的方法,类似JAVA 语言中的构造方法。每当创建一个类的新实例时,Python都会自动执行它。init()方法必须包含一个参数,并且必须是第一参数。self参数是一个指向实例本身的引用,用于访问类中的属性和方法。
在方法调用时会自动传递实际参数self。因此,当__init__()方法只有一个参数时,在创建类的实例时,就不需要指定参数了。
# 创建类 class Geese: """大雁类""" def __init__(self): print("我是大雁类") wildGoose = Geese()
在__init__()方法中,除了self参数外,还可以自定义一些参数,参数间使用逗号“,”进行分隔。例如,下面的代码将在创建__init__()方法时,再指定3个参数,分别是beak、wing和claw:
# 创建类 class Geese: """大雁类""" def __init__(self, beak, wing, claw): print("我是大雁类!我有一下特征:") print(beak) print(wing) print(claw) beak_1 = "喙" wing_1 = "翅膀" claw_1 = "爪" wildGoose = Geese(beak_1, wing_1, claw_1)
五、类的成员
类的成员主要由实例方法和数据成员组成。
5.1 实例方法
所谓实例方法是指在类中定义函数。该函数是一种在类的实例上操作的函数。同__init__()方法一样,实例方法的第一参数必须是self,并且必须包含一个self参数。
def functionName(self,parameterlist): block
访问实例方法,通过类的实例名称和点(.)操作符进行访问
instanceName.functionName(parametervalue)
5.2数据成员
5.2.1 类属性
类属性是指在定义类中,并且在函数体外的属性。类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。
1.在实例化对象中是公用的。
2.定义在类中且在函数体之外。
3.通常不作为实例变量使用。
4.ClassName.bianliang来访问
lass Geese: """大雁类""" beak_1 = "喙,比较尖" # 定义类属性(喙) wing_1 = "翅膀,比较大" claw_1 = "爪,行走自如" def __init__(self): print("我是大雁类!我有一下特征:") print(Geese.beak_1) # 输出喙的属性 print(Geese.wing_1) print(Geese.claw_1)
5.2.3 实例属性
实例属性是指定义在类的方法中的属性,只作用于当前实例中。
1.定义在方法中的变量。
2.只作用于当前实例的类。
3.实例名.bianliang来访问
# 创建类 class Geese: """大雁类""" def __init__(self): self.beak_1 = "喙,比较尖" # 定义实例属性(喙) self.wing_1 = "翅膀,比较大" self.claw_1 = "爪,行走自如" print("我是大雁类!我有一下特征:") print(self.beak_1) # 输出喙的属性 print(self.wing_1) print(self.claw_1)
六、访问属性
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。
内置类属性:
__dict__ :类的属性
__doc__ :类的文档字符串
__name__:类名
__module__:类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
__bases__:类的所有父类构成元素(包含了一个由所有父类组成的元组)
七、访问限制
但Python并没有对属性和方法的访问权限进行限制。为了保证类内部的某些属性或方法不被外部所访问,可以在属性或方法名前面添加单下划线(_foo)、双下划线(__foo)或者首尾加双下划线( __ foo __),从而限制访问权限。
__ foo __ :首尾双下划线表示定义特殊方法,也称作魔术方法,一般是系统定于名字,如__init__()
_foo:以单下划线开头的表示protected(保护)类型的成员,只允许类本身或子类访问,但不能使用“ from module impor”语句导入
__foo:双下划线表示private(私有)类型的成员,只允许定义该方法的类本身进行访问即只能在类内部方法中通过self.__foo使用,而且也不能通过类的实例进行访问,但是可以通过“类的实例名.类名 __xxx”方式访问。私有只是一种约定, 隐藏实现的细节,只对外公开我们想让他们使用的属性和方法,这就叫做封装
八、继承
所有类都会继承Object类,父类的构造(__init__())方法不会被自动调用,issubclass(sub,sup) 尔函数判断一个类是另一个类的子类或者子孙类,isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true
class ClassName(baseclasslist): #baseclasslist用于指定要继承的基类,可以有多个,类名之间用逗号“,”隔开。如不指定,将使用所有Python对象的根类object """类的帮助信息""" # 类的文档字符串 statement # 类体
基类的成员都会被派生类继承,当基类中的某个方法不完全适用于派生类时,就需要在派生类中重写父类的这个方法
class Fruit: # 定义水果基类 color = "绿色" # 定义类属性 def harvest(self, color): print("水果是:" + color + "的") # 输出形式参数 print("水果已经收获......") print("水果原来是:" + Fruit.color + "的") # 输出类属性color class Orange(Fruit): # 定义橘子类(派生类) color = "橙色" def __init__(self): print("\n我是橘子") def harvest(self, color): print("橘子是:" + color + "的") # 输出形式参数 print("橘子已经收获......") print("橘子原来是:" + Fruit.color + "的") # 输出类属性color
在派生类中定义__init__()方法时,不会自动调用基类的__init__()方法。因此在派生类中使用基类的__init__()方法,必须要进行初始化,即需要在派生类中使用super()函数调用基类的__init__()方法。
class Fruit: # 定义水果基类 def __init__(self, color="绿色"): Fruit.color = color # 定义类属性 def harvest(self): print("水果原来是:" + Fruit.color + "的") # 输出类属性color class Apple(Fruit): # 定义苹果类(派生类) def __init__(self): print("我是苹果") super().__init__() # 调用基类的__init__()方法 apple = Apple() # 创建类的实例(苹果) apple.harvest() # 调用基类的harvest()方法
九、多态
必要条件 要有继承+重写 即使多态
十、封装
python的面向对象, 并没有严格意义上的私有属性和方法, 私有只是一种约定, 隐藏实现的细节,只对外公开我们想让他们使用的属性和方法,这就叫做封装,封装的目的在于保护类内部数据结构的完整性, 因为使用类的用户无法直接看到类中的数据结构,只能使用类允许公开的数据,很好地避免了外部对内部数据的影响,提高了程序的可维护性。用户只能通过暴露出来的方法访问数据时,你可以在这些方法中加入一些控制逻辑,以实现一些特殊的控制
十一、析构函数
用于初始化类的内容部状态,Python提供的构造函数式 __init__(),也就是当该类被实例化的时候就会执行该函数,__init__()方法是可选的,如果不提供,Python 会给出默认的__init__方法。
“__del__”是析构函数,当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用域的同时析构函数也会被调用一次,这样可以用来释放内存空间。
__del__()也是可选的,如果不提供,则Python 会在后台提供默认析构函数
如果要显式的调用析构函数,可以使用del关键字: del obj