类和实例
面向对象最重要的概念就是类(class)和实例(instance),类是抽象的模板,而实例是根据类创建出来的具体的‘对象’。
- L类是创建实例的模版,而实例是一个一个对象,各个实例拥有的数据都互相独立,互不影响
- 方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据
- 通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节.
- 和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Student(object):
def __init__(self,name,score):
self.name = name
self.score = score
def print_score(self):
print('打印 第一个实例对象' + self.name)
#bart = Student('Bart Simpson',59)
#print_score(bart)
def get_grade(self):
if self.score >= 90:
return 'A'
elif self.score >= 60:
return 'B'
else:
return 'C'
lisa = Student('lisa',65)
print('打印lisa的成绩: ' + get_grade(lisa))
访问限制
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
#bart = Student('Bart Simpson',59)
#print_score(bart)
def get_grade(self):
if self.score >= 90:
return 'A'
elif self.score >= 60:
return 'B'
else:
return 'C'
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
if 0 <= score <= 100:
self.__score == score
else:
raise ValueError('bad score')
bart = Student('lusy',65)
print(bart.get_score())
#print('bart.get_name ='+bart.get_name())
bart.set_score(92)
print(bart.get_score())
继承和多态
-
对扩展开放:允许新增Animal子类
-
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数
-
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写.
-
动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的.
获取对象信息
- type()函数 判断基本类型 如果一个变量指向函数或者类,也可以用type()
>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>
>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(a)
<class '__main__.Animal'>
>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)
False
- isinstance() 判断class的类型
- isinstance() 能用type()判断的基本类型也可以用isinstance()判断
- 总是优先使用isinstance判断类型,可以将指定类型及其子类‘一网打尽’
obj = Main()
print(hasattr(obj,'x'))
# true
print(hasattr(obj,'y'))
# false
setattr(obj,'y',18)
print(hasattr(obj,'y'))
-
使用dir() 如果要获得一个对象的所有属性和方法,返回一个包含字符串的list
-
通过内置的一系列函数,我们可以对任何一个python对象进行剖析,拿到其内部的数据。
实例属性和类属性
- 实例属性属于各个实例所有,互不干扰
- 类属性属于类所有,所有实例共享一个属性
- 不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误
>> class Student(object):
... name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student
网友评论