类是模板,而实例则是根据类创建的对象。片面的认为它是一个种类,它是相似特征的抽像,也就是相似的东西,可以把相似特征的事务抽象成一个类。(事务可以是具体的物体或行为)
1.类的定义与实例的创建
class Circle(object): # 创建Circle类,Circle为类名
pass # 此处可添加属性和方法
创建两个Circle类的实例:
circle1= Circle()
circle2= Circle()
2.类的实例属性与类属性
实例属性可以用于区分每个实例;类属性是每个实例的共有属性。实例属性每个实例各自拥有,互相独立,而类属性有且只有一份
实例属性
circle1.r = 1 # r为实例属性
circle2.R= 2
print(circle1.r) # 使用 实例名.属性名 可以访问我们的属性
print(circle2.R)
circle1 = Circle(1) # 创建实例时直接给定实例属性,self不算在内
circle2 = Circle(2)
print(circle1.r) # 实例名.属性名 访问属性
print(circle2.r) # 我们调用实例属性的名称就统一了
class Circle(object): # 创建Circle类
def __init__(self, R): # 约定成俗这里应该使用r,它与self.r中的r同名
self.r = R
circle1 = Circle(1)
print(circle1.r) #我们访问的是小写r
在创建实例时给类初始属性,当创建实例时,__init__()方法被自动调用,就能在此为每个实例都统一加上我们需要的属性
class Circle(object): # 创建Circle类
def __init__(self, r): # 初始化一个属性r(不要忘记self参数,他是类下面所有方法必须的)
self.r = r # 表示给我们将要创建的实例赋予属性r赋值
类属性
在类上绑定属性,则所有实例都可以访问该类的属性,并且所有实例访问的类属性都是同一个可见,千万不要在实例上修改类属性,它实际上并没有修改类属性,而是给实例绑定了一个实例属性。
class Circle(object):
pi = 3.14 # 类属性
def __init__(self, r):
self.r = r
circle1 = Circle(1)
circle2 = Circle(2)
print(circle1.pi) #输出3.14
Circle.pi = 3.14159 # 通过类名修改类属性,所有实例的类属性被改变
print(circle1.pi) #输出3.14159
circle1.pi=3.14111 # 实际上这里是给circle1创建了一个与类属性同名的实例属性
print(circle1.pi) #输出3.14111 实例属性的访问优先级比类属性高
print(circle2.pi) #输出3.14159
del circle1.pi
print(circle1.pi) #输出3.14159
3.类的实例方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同。类方法必须第一个参数为 self, self 代表的是类的实例(即你还未创建类的实例)其他参数和一个普通函数是完全一样。
class Circle(object):
pi = 3.14 # 类属性
def __init__(self, r): #特殊的实例方法
self.r = r # 实例属性
def get_area(self): #求圆的面积的方法
return self.r**2 * self.pi
circle1 = Circle(1)
print(circle1.get_area()) # 调用方法 self不需要传入参数,不要忘记方法后的括号 输出3.14
Circle.pi使用的是类属性pi,我们通过创建的实例去修改pi的值对它无影响。self.pi为实例的pi值,我们通过创建的实例去修改pi的值时,由于使用self.pi调用的是实例属性,所以self.pi是修改后的值。
4.参数的传递图
1和2参数传递给__init__方法中的data参数;3self参数指向当前实例自身,self代表创建的实例变量ik1或者Kls('arun')
我们不需要传递实例自身给方法,Python解释器自己会做这些操作的;ik1会自动作为第一个实例参数(self)传入方法中
5.类中的访问限制(常用)
属性的访问限制,Python私有属性
如果有些属性不希望被外部访问,可以属性命名时以双下划线开头;改属性不能使用原变量名访问,使属性变为私有的(伪私有)
__pi = 3.14
通过Circle.__pi与circle1.__pi访问__pi时 都会出现AttributeError异常,证明访问权限已被控制;可以通过 Circle._Circle__pi 访问到__pi 属性;以"__xxx__"定义的属性在Python的类中被称为特殊属性
方法的访问限制,Python私有访问
同属性的访问限制,方法的访问限制也是在方法名前加双下划线(__),它也是一种伪私有
def __girth(self): #圆的周长
return 2*self.r * self.__pi
circle1 = Circle(2)
print(circle1.__girth()) # 抛出AttributeError异常
访问被限制的方法也是 _类名__xx 如circle1._Circle__girth()
6.类中的@classmethod、@staticmethod 装饰方法
@classmethod 类方法
使用在与类进行交互,但不和其实例进行交互的函数方法上。我们不用通过实例化类就能访问的方法。而且@classmethod装饰的方法不能使用实例属性,只能是类属性。它主要使用在和类进行交互,但不和其实例进行交互的函数方法上。只在类中运行而不在实例中运行的方法,简单示例,读取私有化类属性数据,如下:
class Circle(object):
__pi = 3.14
def __init__(self, r):
self.r = r
@classmethod
def pi(self):
return self.__pi
def area(self):
return self.r ** 2 * self.__pi
print(Circle.pi()) # 没有实例化 能直接访问pi() 方法
circle1 = Circle(2)
print(circle1.pi()) # 也可以通过实例访问pi()方法
class Date(object):
day = 0
month = 0
year = 0
def __init__(self, year=0, month=0, day=0):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, date_as_string):
year, month, day = date_as_string.split('-')
date = cls(year, month, day)
return date
date1 = Date.from_string('2017-10-17')
print(date1.year, date1.month, date1.day)
from_string 返回的是Date类的实例,所以我们可以通过from_string 实例化类。
from_string(cls, date_as_string)中cls表示的是类,它和self类实例有一定的差别。类方法中都是使用cls,实例方法中使用self。
@staticmethod 静态方法
使用在有些与类相关函数,但不使用该类或该类的实例。如更改环境变量、修改其他类的属性等。做的事与类方法或实例方法一样。@staticmethod 修饰的方法是放在类外的函数,我们为了方便将他移动到了类里面,它对类的运行无影响
class Date(object):
day = 0
month = 0
year = 0
def __init__(self, year=0, month=0, day=0):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, date_as_string):
year, month, day = date_as_string.split('-')
date = cls(year, month, day)
return date
@staticmethod
def is_date_valid(date_as_string): #用来校验日期的格式是否正确
year, month, day = date_as_string.split('-')
return int(year) <= 3999 and int(month) <= 12 and int(day) <= 31
date1 = Date.from_string('2012-05-10')
print(date1.year, date1.month, date1.day)
is_date = Date.is_date_valid('2012-09-18')
print(is_date) #返回True
7.property使用
@property将类方法转换为只读属性(常用)
将它作为装饰器来使用,可以将一个类方法转变成一个类属性。只能读不能修改
property重新实现setter和getter方法(少用)
把一个getter方法变成属性,只需要加上@property就可以了,如上此时pi(self)方法,@property本身又创建了另一个装饰器@pi.setter,负责把一个setter方法变成属性赋值,于是,将@pi.setter加到pi(self, pi)上,我们就拥有一个可控的属性操作。
class Circle(object):
__pi = 3.14
def __init__(self, r):
self.r = r
@property
def pi(self):
return self.__pi
@pi.setter
def pi(self, pi):
Circle.__pi = pi
circle1 = Circle(2)
circle1.pi = 3.14 # 设置 pi的值
print(circle1.pi) # 访问 pi的值