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__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:

 

posted on 2016-07-06 21:34  张明明_1  阅读(231)  评论(0编辑  收藏  举报

导航