类:类是抽象的模板。
实例:实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法
如何定义一个类?如下,什么叫做实例化? 如下
class Avengers(object):#继承总的基类
pass #定义完一个类
avengers=Avengers()#称之为实例化
变量avengers指向的就是一个Avengers的实例,每个object的地址都不一样,而Avengers本身则是一个类。
可以自由地给类实例绑定一个属性
avengers.hero1='tony'
print(avengers.hero1)
#>> tony
啥叫属性呢?用大白话就是类内的变量,因为类启到了模板的作用,在创建实例的时候,可以把必须**绑定的属性(变量)**强制填入
class Avengers(object):#继承总的基类
def __init__(self,name,rank): #下横线是双下横线,
self.name=name
self.rank=rank #把形参赋给属性,这样,self.name,self.rank在整个类都有可以使用
avengers=Avengers('thor',3)#此时实例化就要给形参赋值
print(avengers.name,avengers.rank)
#>> thor 3
注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
实例化类之后呢,我们刚刚是通过外部来访问这些属性,但是既然有了这些属性,我们可以利用内部函数这种方法访问
class Avengers(object):#继承总的基类
def __init__(self,name,rank): #下横线是双下横线,
self.name=name
self.rank=rank #把形参赋给属性,这样,self.name,self.rank在整个类都可以使用
def getattribute(self):
print(self.name,self.rank)
avengers=Avengers('thor',3)#此时实例化就要给形参赋值
avengers.getattribute()
getattribute函数是被封装在类里面,好处就是对细节的隐藏。封装的另一个好处就是可以给类增加方法
class Avengers(object):#继承总的基类
def __init__(self,name1,name2,rank1,rank2): #下横线是双下横线,
self.name1=name1
self.rank1=rank1 #把形参赋给属性,这样,self.name,self.rank在整个类都可以使用
self.name2=name2
self.rank2=rank2
def getattribute(self):#有self的好处就是
print(self.name,self.rank)
def rank(self):#新增加的方法
if(self.rank1<=self.rank2):
print(self.name2,self.rank2)
else:
print(self.name1,self.rank1)
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
self的好处就是:在类内的函数调用属性可以不再写形参,self就像是一个随处可改变的指针,想指哪就指哪
访问限制
现在我们类实例里面的属性是很灵活的,随时随地就能被外部的更改(灵活),换个角度就是‘公交车’,怎么样变成‘私家车’呢?
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private)
class bus2car(object):
def __init__(self,name,rank):
self.__name=name
self.__rank=rank
car=bus2car('whoremaster',3)
print(car.__bame)
#>>报错
如果你执意要去获取私有属性怎么办?可以写一个“返回属性的函数”之后调用该函数
人的问题总是超多的,什么?你现在又想改私有属性??
采取‘曲线救国’的思想
class bus2car(object):
def __init__(self,name,rank):
self.__name=name
self.__rank=rank
def getattribute(self): #间接获取私有属性
return self.__name,self.__rank
def alterattr(self,newname,newrank):#间接改私有属性
self.__name=newname
self.__rank=newrank
car=bus2car('whoremaster',3)
print(car.getattribute())
car.alterattr('John',4)
其实也不一定要曲线救国,可以直接上前线,但是‘很危险’
可以这样
car=bus2car('whoremaster',3)
print(car._bus2car__name)
很危险:因为不同版本的Python解释器可能会把**__name改成不同的变量名**。
实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性。
给实例绑定属性的方法是通过实例变量,或者通过self变量:譬如
class Hero(object):
def __init__(self,name):
self.name=name
Tom_Holland=Hero('spiderman')#通过self变量
Tom_Holland.rank=3 #通过实例变量
但是如果Hero本身就需要绑定一个属性呢?可以这样
class Hero(object):
name='avengers' #类属性
#定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到
#从类访问:
print(Hero.name)
#从实例访问
hero=Hero()
print(hero.name)
注意:实例属性的优先级比类属性高,屏蔽掉类的name属性,但是,仅仅在实例里面,不会影响到类,譬如
hero=Hero()
hero.name='avengers assemable'
print(Hero.neme)
#>>avengers
#如果你 不小心删了实例属性,再次调用实例属性,实例属性会调用类属性(你的公司资产被冻结,但是你还可以‘啃老’)
del hero.name
print(hero.name)
#>>avengers