python的面向对象
1、什么是对象?
在python中,一个对象的特征也称为属性(attribute)。它所具有的行为,或者是函数也称为方法(method)结论:对象=属性+方法
2、 什么是类?
具有相同属性和方法的对象归为一个类(class):类是对象的抽象化,对象是类的实例化,是类定义数据结构的实例。
3、创建类:
class ClassName: #类文档字符串
classname=0 #类变量
def __init__(self, name): # 对象的属性即为name(数据域)
self.name= name # 变量的显性,可用于多态
def methon (self): # 类的方法即为methon
print “类的参数是%s”% self.name
def __str__(self):
return "名字是:%s % (self.name)
obj=ClassName(zhangdan) # 类的实例化
3.1、类的属性
属于对象静态的一面,用来形容对象的一些特性,也称之为数据域。(数据成员:类变量、实例变量、局部变量用于处理类及其实例对象的相关的数据)
(1)类变量:
- 类变量定义在类中且在函数体之外
- 类变量在整个实例化的对象中是公用的,它的值将在这个类的所有实例之间共享
- 可以使用类名直接调用(eg:CLanguage.name)
- 通过类名不仅可以调用类变量,也可以修改它的值
- 注意,通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量
(2)实例变量:以“self.变量名”的方式定义的变量
- 定义在方法中的变量,只作用于当前实例的类
- 实例变量只能通过对象名访问,无法通过类名访问
(3)局部变量:除了实例变量,类方法中还可以定义局部变量。和前者不同,局部变量直接以“变量名=值”的方式进行定义,例如:
- 定义局部变量是为了所在类方法功能的实现
- 局部变量只能用于所在函数中,函数执行完成后,局部变量也会被销毁
(4) Python内置类属性:
- __dict__ : 类的属性(由类的数据属性组成的字典)
- __doc__ :类的文档字符串
- __name__: 类名
- __module__: 类定义所在的模块
- __bases__ : 类的所有父类构成元素(由所有父类组成的元组)
- __class__:指向类
3.1.1、类的私有属性
- __foo__: 定义的是特列方法,类似 __init__() 之类的
- _protected_attrs: 以单下划线开头,表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
- __private_attrs: 两个下划线开头,声明该属性为私有,不能在类的外部或子类被使用。在类内部的方法中使用时 self.__private_attrs
补充:如果类被设计用来给其他程序使用,为了避免数据被篡改,就要设置成隐藏数据域,即两个下划线开头,可以使用def getname()来读取
3.2、类的方法
属于对象动态的一面,使用方法来操作一个对象
(类方法也可以进行更细致的划分,具体可分为类方法、实例方法和静态方法,采用 @classmethod 修饰的方法为类方法;采用 @staticmethod 修饰的方法为静态方法;不用任何修改的方法为实例方法。)
(1)实例方法:
- 使用 def 关键字可以为类定义一个(函数)方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)
- 方法调用
- 1.类的内部调用:self.<方法名>(参数列表)
- 2.在类的外部调用:<实例名>.<方法名>(参数列表)
- 3.使用类名调用:用类的实例对象访问类成员的方式称为绑定方法,而用类名调用类成员的方式称为非绑定方法。
- self含义:self 所表示的是实际调用该方法的对象,无论是类中的构造函数还是普通的类方法,实际调用它们的谁,则第一个参数 self 就代表谁。事实上,Python 只是规定,无论是构造方法还是实例方法,最少要包含一个参数,并没有规定该参数的具体名称。之所以将其命名为 self,只是程序员之间约定俗成的一种习惯,遵守这个约定,可以使我们编写的代码具有更好的可读性(大家一看到 self,就知道它的作用)。那么,self 参数的具体作用是什么呢?打个比方,如果把类比作造房子的图纸,那么类实例化后的对象是真正可以住的房子。根据一张图纸(类),我们可以设计出成千上万的房子(类对象),每个房子长相都是类似的(都有相同的类变量和类方法),但它们都有各自的主人,那么如何对它们进行区分呢?当然是通过 self 参数,它就相当于每个房子的门钥匙,可以保证每个房子的主人仅能进入自己的房子(每个类对象只能调用自己的类变量和类方法)也就是说,同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。如此,Python解释器就能知道到底要操作哪个对象的方法了。因此,程序在调用实例方法和构造方法时,不需要手动为第一个参数传值。例如,更改前面的 Person 类,如下所示:
class Person:
def __init__(self):
print("正在执行构造方法")
# 定义一个study()实例方法
def study(self):
print(self,"正在学Python")
zhangsan = Person()
zhangsan.study()
lisi = Person()
lisi.study()
上面代码中,study() 中的 self 代表该方法的调用者,即谁调用该方法,那么 self 就代表谁。因此,该程序的运行结果为:
正在执行构造方法<__main__.Person object at 0x0000021ADD7D21D0>正在学Python
正在执行构造方法<__main__.Person object at 0x0000021ADD7D2E48> 正在学Python
构造函数中的 self 参数,其代表的是当前正在初始化的类对象
class CLanguage:
#类构造方法,也属于实例方法
def __init__(self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
# 下面定义了一个say实例方法
def say(self):
print("正在调用 say() 实例方法")
clang = CLanguage()
clang.say()
Python 也支持使用类名调用实例方法,但此方式需要手动给 self 参数传值
#类名调用实例方法,需手动给 self 参数传值
clang = CLanguage()
CLanguage.say(clang)
(2)类方法:和实例方法最大的不同在于,类方法需要使用@classmethod修饰符进行修饰
- 使用@classmethod修饰符进行修饰
- Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参。(和 self 一样,cls 参数的命名也不是规定的(可以随意命名),只是 Python 程序员约定俗称的习惯而已)
- #使用类名直接调用类方法:<类名>.<方法名>(参数列表)
(3)静态方法:静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。
- 静态方法需要使用@staticmethod修饰
- 静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。
- 静态方法的调用,既可以使用类名,也可以使用类对象
3.2.1、 __init__():类的默认构造方法
该方法是一个特殊的类实例方法,称为构造函数,当创建了这个类的实例时就会自动调用该方法,即便不手动为类添加任何构造方法,Python 也会自动为类添加一个仅包含 self 参数的构造方法,用于对象的初始化
__init__()方法意义重大的原因有两个:
- 第一个原因是在对象生命周期中初始化是最重要的一步;每个对象必须正确初始化后才能正常工作。
- 第二个原因是__init__()可以自定义一些参数,参数之间使用逗号“,”进行分割。
3.2.2、def __str__(self):自带函数 """返回一个对象的描述信息"""
- 当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
- __str__方法需要返回一个字符串,当做这个对象的描写
3.2.3、类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类外部调用。在类的 内部调用 self.__private_methods