代码改变世界

python 第六天

2018-12-03 13:49  小于漫谈  阅读(139)  评论(0编辑  收藏  举报

面向对象介绍:

1、面向对象有两大特性:

1.1、class:

一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法

1.2、object:

一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同

class Dog(object):
def __init__(self,name): #构造函数,在实例化时做一些类的初始化工作,self是每次实例化d1或者d2那个内存空间,就是实例本身
self.name = name #实例变量(静态属性)
def bulk(self): #类的方法,功能(动态属性),这里的self也是表示实例化的本身,因为要调用相关的内存空间
print("%s wang wang wang!" %self.name)

#d1 = Dog("test1")此时self相当于d1,Dog(d1,"test1")
d1 = Dog("test1") #Dog类的实例,代表吧d1.test1传给了Dog类,这样子self就是d1本身
d2 = Dog("test2") #生成一个实例,会自动把参数穿个Dog下的__init__(.....)

d1.bulk() #只有经过实例化后,才能调用类中的方法
d2.bulk()

2、类的3大特性

2.1、封装

在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法

其实就是使用构造方法将内容封装到某个具体对象中,然后通过对象直接或者self间接获取被封装的内容

2.2、继承

一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承

class People(object):  
def __init__(self,name,age):
self.name = name
self.age = age

def eat(self):
print("%s is eating.." %self.name)

def talk(self):
print("%s is talking..." %self.name)

def sleep(self):
print("%s is sleeping.." %self.name)

class Relation(object):
def make_friends(self,obj):
print("%s is making friends with %s " %(self.name,obj.name))
class Man(People,Relation):
  def __init__(self,name,age,money):
    super(Man,self).__init__(name,age) #广式继承父类的相关属性,不用自己再声明了,父类已经声明好了
    self.money = money #父类中没有的属性,再进行声明
    print("%s 一出生就有 %s" %(self.name,self.money))
  def piao(self):
    print("%s is piaoing ..... 20s... done" %self.name)
  def sleep(self): #如果这里有的话,就不会执行父类的方法,这叫重构父类方法
    People.sleep(self) #先继承了父类的方法
    print("man is sleeping")

class Woman(People): #Woman类完全继承了People中的静态属性,没有对静态属性进行重构
  def get_birth(self): #新加了方法
    print(“%s is born a baby” %self.name)

m1 = Man("test1",'18',100000) #必须传入三个参数
m1.eat() #其实调用了父类的中方法
m1.sleep() #调用的是自己中的方法,只不过继承了父类的方法
w1 = Woman("test2","20")
m1.make_friends(w1) #因为上边的m1继承了Relation类,make_friends中又传入两个参数,一个是类本身和另一个类
这句话的意思是 make_friends(m1,w1) 这样子就不难理解每次写self意义了,还有就是每次实例化为什么写 m1 = Man()

2.3、多态
简单的说就是一种方法,多种形态,多态的目标是实现一个接口的重复利用
class Animal(object):
def __init__(self, name): # Constructor of the class
self.name = name

def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")

@staticmethod #静态函数就是和类没有直接关联的,所以animal_talk(self)没用
def animal_talk(obj):
obj.talk()

class Cat(Animal):
def talk(self):
print('%s: 喵喵喵!' % self.name)


class Dog(Animal):
def talk(self):
print('%s: 汪!汪!汪!' % self.name)


# def func(obj): # 一个接口,多种形态
# obj.talk()


c1 = Cat('小晴')
c1.talk() #标准情况下,可以调用类下自己的方法,所以方法里没有任何参数
d1 = Dog('李磊')

Animal.animal_talk(c1) #静态方法中,因为和类没有直接关系,所以可以传入自己定义的参数
Animal.animal_talk(d1)
3、类的特殊方法:
3.1、静态方法,就是类不能直接调用了自己的函数了,和类没有直接关系了,需要传入相应的参数,上边例子已经有了。
3.2、类方法:类方法只能访问类变量,不能访问实例变量
class Dog(object):
n = “yun”
def __init__(self,name):
self.name = name

@classmethod
def eat(self):
print("%s is eating %s" %(self.n,'flood'))


d = Dog("Test")
d.eat() #d.eat()中执行的结果是:yun is eating flood,而不是Test is eating flood,因为此方法调用不了实例的参数,只能调类中的yun
3.3、属性方法:
将类中的方法变为类的属性,调用的时候,只能用f.flight_status 而不能用 f.flight_status()
class Flight(object):
def __init__(self,name):
self.flight_name = name


def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1


@property #将方法变为属性
def flight_status(self):
status = self.checking_status() #在这里进行调用了方法
if status == 0 :
print("flight got canceled...")
elif status == 1 :
print("flight is arrived...")
elif status == 2:
print("flight has departured already...")
else:
print("cannot confirm the flight status...,please check later")

f = Flight("747")
f.flight_status
此时遇到有一个问题,不能对类的属性进行赋值,比如你想f.flight_status = 2,是不允许进行直接赋值的,如果想直接赋值,需要加装饰器:
@flight_status.setter @flight_status.deleter
如下:
    @flight_status.setter #修改
def flight_status(self,status):
status_dic = {
0 : "canceled",
1 :"arrived",
2 : "departured"
}
print("\033[31;1mHas changed the flight status to \033[0m", status_dic[status])
#又get到新的技能,字典可以用get方法,status_dic.get() status_dic.get(status)

@flight_status.deleter #删除
def flight_status(self):
print("status got removed...")

f = Flight("CF747")
f.flight_status
f.flight_status = 2
del f.flight_status
f.flight_status

3.4、反射:通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
# #### 检查是否含有成员 ####
hasattr(obj, 'name') hasattr(obj, 'func')

# #### 获取成员 ####
getattr(obj, 'name') getattr(obj, 'func')

# #### 设置成员 ####
setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1)

# #### 删除成员 ####
delattr(obj, 'name') delattr(obj, 'func')

def bulk(self):
print("%s is yelling..." %self.name)
class Dog(object):
def __init__(self,name):
self.name = name

def eat(self,food):
print("%s is eating..."%self.name,food)



d = Dog("NiuHanYang")
choice = input(">>:").strip() #此处



if hasattr(d,choice): #假如有这个属性
delattr(d,choice) #删除方法需要输入eat()
fun = getattr(d,choice) #输入的是eat,choice就是eat中的food这个参数,这是对方法的处理
fun("2018") #赋值的相当于是eat中的food
attr = getattr(d,choice)
setattr(d,choice,"33") #这是对类中的属性进行修改
print(d.age)
else:
setattr(d,choice,bulk) #把外部的函数装到类里边,此时bulk会变成choice中输入的字符,比如输入talk
d.talk(d)
# setattr(d,choice,22) #动态属性的添加
# print(getattr(d,choice))

# print(d.name)

4、异常处理
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面。
def bulk(self):
print("%s is yelling..." %self.name)
class Dog(object):
def __init__(self,name):
self.name = name

def eat(self,food):
print("%s is eating..."%self.name,food)



# d = Dog("NiuHanYang")
# choice = input(">>:").strip()
# getattr(d,choice)

data = {}
names = [1,2]

try: #程序正常就正常执行
# names[3]
# data['name']
open("tes.txt")
# a = 1
# print(a)
# except Exception as e:
# print("出错了",e)
except (KeyError,IndexError) as e: #具体的错误类型
print("没有这个key",e)
except IndexError as e:
print("列表操作错误",e)
except Exception as e: #不管是什么错误类型
print("未知错误",e)
else: # #主代码块执行完,执行该块
print("一切正常")
finally: # 无论异常与否,最终执行该块
print("不管有没有错都执行")