面向对象
- 面向对象编程:Object Oriented Programming
- 简称:OOP- 把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
- 理解:面向对象中,是类与实例的关系,放在现实中人(包括了男人,女人)它是一个类,小军是人这类的具体某一个人,被叫为实例
- 百度理解:
https://baike.baidu.com/item/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/2262089?fr=aladdin
- - - - - - - -
- 类和实例:
- 类:是抽象出的模版,如人
- 定义方法:
class 类名(object):
object是继承的类,每个类默认都继承object - 代码:
# 创建类 class People(object): pass
- 实例:根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
- 使用方法:
实例名 = 类()
- 代码:
# 实例化类 man = People()
__init__
:初始化类模版,使在初始化时候就能得到属性的值- 代码:
class Student(object): def __init__(self,name,age): # self 这个值不用传 self.name = name # 属性 self.age = age bart = Student('小军','15') # 调用实例属性 print(bart.name,bart.age)
- self:注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
- 方法:类中的函数,与普通函数不同的点在于第一个参数永远是self
- 代码:
class Animal(object): # 属性(变量) name = 'xx' # 方法 def run(self): return self.name + '会跑' monkey = Animal() print(monkey.run())
- - - - - - -
- 数据封装:在类方法中定义一个访问类属性的方法,属性都是在类的内部定义的,这些数据和逻辑被“封装”起来了,调用很容易,但却不用知道内部实现的细节。
代码:
class School(object): def __init__(self,name,addr) self.name = name self.addr = addr # 定义一个方法 直接拿到属性 def getProperty(self): return self.name,self.addr # 实例类 school = School('mslg','America') sName,sAddr = school.getProperty() print(sName,sAddr)
- 访问限制:如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
- 代码:
class Man(object): def __init__(self,name,age): self.__name = name self.__age = age def printNameAge(self): print(self.__name,self.__age) m = Man('a','12') print(m.__name) # 无法访问
- 外部无法访问私有变量:可以创建set方法设置私有变量的值,get方法返回私有变量的值
代码:
# 测试:
```
class Student(object):
def init(self, name, gender):
self.name = name
self.__gender = gender # 私有属性
def set_gender(self,gender): # 设置私有属性的值,并进行参数校验
if gender in ['male','female']:
self.__gender = gender
else:
raise ValueError('gender is male or female')
def get_gender(self): # 得到私有属性值的方法
return self.__gender
bart = Student('Bart', 'male')
if bart.get_gender() != 'male':
print('测试失败!')
else:
bart.set_gender('female')
if bart.get_gender() != 'female':
print('测试失败!')
else:
print('测试成功!')
```
- - - - - -
- 代码:
- 继承和多态:在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
- 代码:
# 定义一个Dog类继承Animal类 class Dog(Animal): pass # 继承之后就拥有了父类非私有方法和属性 d = Dog() print(d.run()) # 调用父类的run方法
- 对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类
- 如果父类和之类拥有同一个方法(方法名,参数个数一致)调用的则是子类的方法
- 代码:
# 定义一个Cat类继承Animal类 class Cat(Animal): name = 'dog' def run(self): return self.name + '会跑' c = Cat() c.run # 调用的是Cat的run方法 print(c.run())
- 多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思:
代码:
```
# class 也是数据类型
isinstance(c,Animal)
isinstance(c,Cat)
print(isinstance(c,Animal),isinstance(c,Cat)) # Cat的实例是Cat数据类型,也是Animal数据类型
isinstance(monkey,Dog)
print(isinstance(monkey,Cat)) # Animal的实例不是Cat数据类型# 定义一个方法传入Animal类型
class Monkey(Animal):
def do_run(Animal):
print(Animal.run())
name = 'monkey'
def run(self):
return self.name + '会跑'
# 调用
do_run(Cat())
do_run(Monkey())
do_run(Dog())
do_run(d)
```
- - - -
- 代码:
- 获取对象信息:
- types:判断一个对象是否是函数
- 实例:
# types import types def fn(): pass type(fn) == types.FunctionType # 返回True
- dir():如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
代码:
```
```
print(dir('123'))
print(dir(Anmial()))- getattr()、setattr()以及hasattr():
代码:
```
# getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:class Demo(object):
name = 'xxx123'
age = 12
def eat(self):
print("eat!!!")
demo = Demo()# hasattr(对象,属性) 检查对象是否有属性,返回布尔值
hasattr(demo,'name') # 有属性 name嘛? True# setattr(对象,属性名,值) 设置一个属性
setattr(demo,'addr','beijin')print(demo.addr) # 获取属性
# getattr(对象,属性) 获取属性的值
getattr(demo,'addr')print( hasattr(demo,'name') )
print( getattr(demo,'addr') )
```