1、__ intit__(self,x,xx,xxx,...)
采用__ init__(self,,xx,xxx,xxxx,...)方法在创建实例时就把属性绑上去,第一个参数一定是self,self指向创建的实例本身
和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,其他并没有什么差别。但是采用对象编程的一个特点就是数据封装
和静态语言不同,python允许对实例变量绑定任何数据,比如原本Student类中只有name,score两个属性,但是bart.age=18,可以得到一个新的age属性,但是也只是这个实例有这个属性,Student类中的其他实例并不会有这个age属性。
2、访问限制
私有变量:在属性前面加两个下划线,如 _ _ name
特殊变量:属性名称前后都加两个下划线,如 _ _ name _ _ ,特殊变量在外部可以直接访问,不是私有变量
私有变量是习惯默认外部不能访问,但是python中在外部其实是可以访问的,但是python解释器会改变名称,如 _ _ name,python会改成_ class名__name(不同解释器的名字可能会不同,所以最好不要在外部直接访问)
如果想在外部访问私有变量,可以采用下面这种方法:
class Student(object): pass... def get_name(self): return self.__name def get_score(self): return self.__score
如果允许外部修改,可以采用下面方法:
class Student(object): ... def set_score(self, score): self.__score = score
虽然当取消私有变量时可以直接修改,但是采用这种方法可以对参数进行检查,防止传入无效参数,比如上面的例子,可以在set_score函数里面判断分数是否在0——100。
class Student(object): def __init__(self,name,score): self.__name=name #加__就把变量变为私有的了,外部不能访问 self.__score=score def print_score(self): if self.__score>=90: print(self.__name,self.__score,'A') elif self.__score>=60: print('%s:%s %s' % (self.__name,self.__score,'B')) else: print('%s:%s %s'%(self.__name,self.__score,'C')) bart = Student('bart',99) lisa=Student('lisa',20) lili=Student('lili',66) bart.print_score() lisa.print_score() lili.print_score() print(bart._Student__name) #私有变量其实在外部是可以访问到的,只是python解释器自动改成了_Stident__name,但是最好不要这样做,因为不同版本的python解释器可能会把__name改成不同的名字 bart.__name='new name' print(bart.__name) #因为python解释器把__name改了名字,所以其实这里的bart.__name其实是一个新的变量,原来的bart.__name现在叫做bart._Student__name print(bart._Student__name)
结果如下:
3、继承和多态
所有的类最终都会继承object类,所以,没有直接继承的类时,就写class xx(object),有直接继承的类时,括号里面就是父类,如class Dog(Animals) (类的名字一般首字母大写)。
定义一个类就相当于定义了一种数据类型,如:
a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型
#判断变量是否是某个类型,可以用 isinstance
>>> isinstance(a, list) True >>> isinstance(b, Animal) True >>> isinstance(c, Dog) True
但是由于Dog是Animals的子类,所以c也是Animals类型:
>>> isinstance(c, Animal)
True
所以当参数是Animals的函数,传入参数为Animals子类的实例时,也是可以运行的,体现了多态性,即当参数为Animals或子类时,实际调用是看当前的具体对象,调用相应的函数或方法,如下例,函数run_twice是以Animals为参数,但是run_twice(Dog()),run_twice(Tortoise())都可以运行,并且是他们对应的run函数:
class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): def run(self): print('Dog is running...') class Tortoise(Animal): def run(self): print('Tortoise is running slowly...') def run_twice(Animal): #其实在python中,这里的参数不一定为Animals类型(鸭子类型),只要有run函数,不管参数是什么,都可以调用,不过具体调用还是看当前对象及相应方法 Animal.run() Animal.run() >>> run_twice(Animal()) Animal is running... Animal is running... >>> run_twice(Dog()) Dog is running... Dog is running... >>> run_twice(Tortoise()) Tortoise is running slowly... Tortoise is running slowly...
但是对于python这样的动态语言来说,继承并没有静态语言严格,即如果不是Animals的子类,只要其中含有run方法,则也可调用run_twice函数: