面向对象编程
一.类和实例
class Student(object): pass
-
class后面是类名,类名通常是大写开头的单词
-
(object)
表示该类是从那个类继承下来的,如果没有合适的继承类,就使用object类,所有类最终都会继承的类 -
创建实例:类名+() ,Student()
-
可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的
__init__
方法
class Student(object): def __init__(self,name, score): self.name = name self.name = score
注意:
-
__init__
的第一个参数永远是self
,表示创建实例本身,在__init__
方法内部,就可以把各种属性绑定到self
,因为self
就指向创建的实例本身。 -
创建实例时要传参进去
-
和普通函数相比,在类定义的函数的第一个参数永远是实例self,调用时不用传该参数,除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。
二.访问控制
如果要让外部不能访问内部的属性和方法,可以把属性的名称前加上两个下划线__
, 实例的变量名如果以__
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
class Student(object): def __init__(self, name, score): self.__name = name self.__score = score
可以留一个接口出来访问或者修改实例中的数据
class Student(object): ... def get_name(self): return self.__name def get_score(self): return self.__score def set_score(self,score): self.score = score
-
变量名类似
__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。 -
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问
__name
是因为Python解释器对外把__name
变量改成了_Student__name
,所以,仍然可以通过_Student__name
来访问__name
变量
bart._Student__name
三.继承和多态
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
class Animal(object): def run(self): print('Animal is running')
可以继承上述类
class Cat(Animal): pass
判断一个变量是否是某个类型可以用isinstance()
判断
isinstance(a, Animal)
多态:
对于一个变量,我们只需要知道它的父类的类型,无需确切知道它的子类型,可以放心调用其方法,而确定调用方法是谁的方法可以在运行中确定。
Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()
方法,返回其内容。但是,许多对象,只要有read()
方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()
方法的对象。
四.获取对象信息
1.type()
用来判断对象类型的
-
type()
返回的是class类型
如果要判断一个对象是否是函数怎么办?可以使用types
模块中定义的常量
import types def fn(): pass type(fn) = types.FunctionType True >>> type(abs)==types.BuiltinFunctionType True >>> type(lambda x: x)==types.LambdaType True >>> type((x for x in range(10)))==types.GeneratorType True
2.isinstance()
对于class的继承关系来说,使用type()
就很不方便。要判断class的类型,可以使用isinstance()
函数
语法:
isinstance(要检测的对象,检测的类型) #返回结果为True或False
能用type()
判断的基本类型也可以用isinstance()
判断
isinstance(1, int) isinstance("a",str)
还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple
isinstance([1,2,3],(list, tuple))
优先使用isinstance()
3.dir()
获取一个对象的属性和方法,返回一个包含字符串的
list
获取一个str
类型的属性和方法
dir(str) #['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
仅仅把属性和方法列出来是不够的,配合getattr()
、setattr()
以及hasattr()
五.实例属性和类属性
实例绑定属性的方法是通过实例变量,或者通过self
变量。
class Student(object): def __init__(self, name): self.name = name
如果在类中绑定属性,直接在class添加属性,这种属性是类属性,归类所有
class Student(object): name = "wang"
属性虽然归类所有,但类的所有实例都可以访问到
注意: 不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。