类
class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print('%s:%s' %(self.__name, self.__score)) def set_score(self, score): if 0 <= score <= 100: self.__score = score else: raise ValueError('bad score')#报错的时候报bad score bart = Student('Bart Simpson', 59)
class Animal(object):#继承自object def run(self): print('Animal is running...') class Tortoise(Animal):#继承自Animal def run(self): print('Tortoise is running slowly...') def run_twice(animal): animal.run() animal.run() #对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。 #对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了: class Timer(object): def run(self): print('Start……')
bart.set_score(99) #bart.set_score(120) 这句会报错:bad score bart.print_score()
需要注意的是,在Python中,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量:
如果要获得一个对象的所有属性和方法,可以使用dir()函数
,它返回一个包含字符串的list,比如,获得一个str对象的
所有属性和方法:
dir('ABC')
print(dir('abc')) #类似__xxx__的属性和方法在Python中都是有特殊用途的,比如__len__方法返回长度。在Python中,如果你调用len()函数试图获取一个对象的长度,实际上,在len()函数内部,它自动去调用该对象的__len__()方法,所以,下面的代码是等价的: print(len('ABC')) print('ABC'.__len__()) class MyDog(object): def __len__(self): return 100 print(len(MyDog())) #lower()返回小写的字符串 print('ABC'.lower())
区分给类绑定实例与给对象绑定实例
class Student(object): def __init__(self, name): self.name = name s = Student('Bob') #给实例帮对属性 s.score = 90 print(s.score) #给类绑定属性 class Student(object): name = 'Student' s = Student() print(s.name) print(Student.name) s.name = 'Michael' print(s.name) print(Student.name) del s.name print(s.name)
class Student(object): pass #尝试给类绑定一个属性 s = Student() s.name = 'Michael' print(s.name) def set_age(self, age): self.age = age from types import MethodType #给实例绑定方法,给一个实例绑定的方法对该类的其他实例不起作用 s.set_age = MethodType(set_age, s) s.set_age(25) print(s.age) #给class绑定方法 def set_score(self, score): self.score = score Student.set_score = set_score s.set_score(22) print(s.score) s2 = Student() s2.set_score(333) print(s2.score) #如果我们想要限制实例的属性怎么办?比如只允许对Student实例增加name和属性 #python允许使用__slots__变量来限制该class实例增加的属性 class Student(object): __slots__ = ('name', 'age') s = Student() s.name = 'rain' print(s.name) #使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的: