您的位置:首页 > 编程语言 > Python开发

python学习日志--day7

2017-07-08 11:59 369 查看

一、面向对象进阶

   1、经典类和新式类

python2 经典类是按深度优先来继承的,新式类是按广度优先来继承的
python3 经典类和新式类都是统一按广度优先来继承的
class A:
def __init__(self):
self.n = 'A'

class B(A):
# def __init__(self):
#     self.n = 'B'
pass

class C(A):
def __init__(self):
self.n = 'C'

class D(B,C):
# def __init__(self):
#     self.n = 'D'
pass

obj = D()

print(obj.n)


继承实例
class School(object):
def __init__(self,name,addr):
self.name = name
self.addr = addr
self.students =[]
self.staffs =[]
def enroll(self,stu_obj):
print("为学员%s 办理注册手续"%stu_obj.name )
self.students.append(stu_obj)
def hire(self,staff_obj):
self.staffs.append(staff_obj)
print("雇佣新员工%s" % staff_obj.name)

class SchoolMember(object):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def tell(self):
pass

class Teacher(SchoolMember):
def __init__(self,name,age,sex,salary,course):
super(Teacher,self).__init__(name,age,sex)
self.salary = salary
self.course = course
def tell(self):
print('''
---- info of Teacher:%s ----
Name:%s
Age:%s
Sex:%s
Salary:%s
Course:%s
'''%(self.name,self.name,self.age,self.sex,self.salary,self.course))
def teach(self):
print("%s is teaching course [%s]" %(self.name,self.course))

class Student(SchoolMember):
def __init__(self,name,age,sex,stu_id,grade):
super(Student,self).__init__(name,age,sex)
self.stu_id = stu_id
self.grade = grade
def tell(self):
print('''
---- info of Student:%s ----
Name:%s
Age:%s
Sex:%s
Stu_id:%s
Grade:%s
''' % (self.name, self.name, self.age, self.sex, self.stu_id, self.grade))
def pay_tuition(self,amount):
print("%s has paid tution for $%s"% (self.name,amount) )

school = School("天津商业大学","天津大学")

t1 = Teacher("Tony",56,"MF",200000,"Linux")
t2 = Teacher("Lucy",22,"M",3000,"PythonDevOps")

s1 = Student("Amy",36,"MF",1001,"PythonDevOps")
s2 = Student("Yimi",19,"M",1002,"Linux")

t1.tell()
s1.tell()
school.hire(t1)
school.enroll(s1)
school.enroll(s2)

print(school.students)
print(school.staffs)
school.staffs[0].teach()

for stu in school.students:
stu.pay_tuition(5000)


输出结果



  多态(一个接口,多个方法,实现接口重用)

class Animal:
def __init__(self, name):  # Constructor of the class
self.name = name

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

@staticmethod
def animal_talk(obj):
obj.talk()

class Cat(Animal):
def talk(self):
print('Meow!')

class Dog(Animal):
def talk(self):
print('Woof! Woof!')

d = Dog("Tony")
#d.talk()

c = Cat("Lucy")
#c.talk()
#
# def animal_talk(obj):
#     obj.talk()

Animal.animal_talk(c)
Animal.animal_talk(d)


输出结果



2、静态方法、类方法、属性方法

静态方法

     通过@staticmethod装饰器使用

可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,
其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法

class Dog(object):

def __init__(self,name):
self.name = name

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

d = Dog("yimi")
d.eat("包子")
正常调用时输出结果



使用静态方法
class Dog(object):

def __init__(self,name):
self.name = name

@staticmethod #把eat方法变为静态方法
def eat(self,food):
print("%s is eating %s" % (self.name,food))

d = Dog("yimi")
d.eat("包子")
此时的输出结果



想要正常输出,有两种方法

 调用时主动传递实例本身给eat方法,即d.eat(d) 

class Dog(object):

def __init__(self,name):
self.name = name

@staticmethod #把eat方法变为静态方法
def eat(self):
print(" is eating ")

d = Dog("yimi")
d.eat(d)

在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了

class Dog(object):

def __init__(self,name):
self.name = name

@staticmethod #把eat方法变为静态方法
def eat():
print(" is eating ")

d = Dog("yimi")
d.eat()


输出结果



类方法
类方法通过@classmethod装饰器实现,
类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

class Dog(object):
n='yimi'

def __init__(self,name):
self.name = name

@classmethod #把eat方法变为类方法
def eat(self):
print("%s is eating "%self.n)

def talk(self):
print("%s is talking "%self.n)
d = Dog("yimi")
d.eat()


输出结果



属性方法

属性方法的作用就是通过@property把一个方法变成一个静态属性

class Dog(object):
#n='yimi'

def __init__(self,name):
self.name = name

@property #把eat方法变为静态方法
def eat(self):
print("%s is eating "%self.name)

d = Dog("yimi")
d.eat   #调用时不能加括号


输出结果



如果需要传参数呢?怎么办?

class Dog(object):

def __init__(self,name):
self.name = name

@property #把eat方法变为静态方法
def eat(self):
print("%s is eating "%self.name)

@eat.setter   #在eat下面再定义一次属性
def eat(self,food):
print("set to food:",food)

d = Dog("yimi")
d.eat   #调用时不能加括号
d.eat = "包子"


输出结果



3、类的特殊成员方法

_doc_   (描述类的描述信息)

_module_和_class_
               _module_表示当前操作的对象在哪个模块,
                   _class_表示你当前操作的对象的类是什么
from lib.aa import C

obj = C()
print(obj.__module__)  # 输出 lib.aa,即:输出模块
print(obj.__class__ )     # 输出 lib.aa.C,即:输出类


_init_(构造方法,通过类创建对象时,自动触发执行)

_del_

_call_(对象后面加括号,触发执行)
class Foo:

def __init__(self):
pass

def __call__(self, *args, **kwargs):

print ('__call__')

obj = Foo() # 执行 __init__
obj()       # 执行 __call__


_dict_(查看类或对象中的所有成员)

_str_(如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值)
class Foo:

def __str__(self):
return 'yimi'

obj = Foo()
print obj
# 输出:yimi


_getitem_、_setitem_、_delitem_(用于索引操作,如字典。以上分别表示获取、设置、删除数据)
class Foo(object):

def __getitem__(self, key):
print('__getitem__',key)

def __setitem__(self, key, value):
print('__setitem__',key,value)

def __delitem__(self, key):
print('__delitem__',key)

obj = Foo()

result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'alex'   # 自动触发执行 __setitem__
del obj['k1']
输出结果



_new_、_metaclass_(python高级装逼技能)
发现实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法,__new__()必须要有返回值,返回实例化出来的实例,需要注意的是,可以return父类__new__()出来的实例,也可以直接将object的__new__()出来的实例返回。

__init__()有一个参数self,该self参数就是__new__()返回的实例,__init__()在__new__()的基础上可以完成一些其它初始化的动作,__init__()不需要返回值。

若__new__()没有正确返回当前类cls的实例,那__init__()将不会被调用,即使是父类的实例也不行。

class Demo(object):

def __init__(self):
print ('__init__() called...')

def __new__(cls, *args, **kwargs):
print ('__new__() - {cls}'.format(cls=cls))
return object.__new__(cls, *args, **kwargs)

if __name__ == '__main__':
de = Demo()输出结果



class MyType(type):
def __init__(self, what, bases=None, dict=None):
print("--MyType init---")
super(MyType, self).__init__(what, bases, dict)

def __call__(self, *args, **kwargs):
print("--MyType call---")

obj = self.__new__(self, *args, **kwargs)
obj.data = {"name":111}
self.__init__(obj, *args, **kwargs)

class Foo(object):
__metaclass__ = MyType

def __init__(self, name):
self.name = name
print("Foo ---init__")

def __new__(cls, *args, **kwargs):   #_new_用来创建实例
print("Foo --new--")
print(object.__new__(cls))
return object.__new__(cls) #继承父亲的__new__方法

# 第一阶段:解释器从上到下执行代码创建Foo类
# 第二阶段:通过Foo类创建obj对象
obj = Foo("Alex")
print(obj.name)
输出结果



 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。



4、反射

hasaddr(obj,name_str)判断一个对象obj里是否有对应的name_str字符串的方法
getattr(obj,name_str) 根据字符串去获取obj 对象里的对应的方法的内存地址
setaddr(obj,'y',z),is equivalent to x.y = v
def bulk(self):
print("%s is sleeplling...." %self.name)
class Demo(object):

def __init__(self,name):
self.name = name

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

d = Demo("yimi")
choice = input(">>:").strip()

#print(hasattr(d,choice))

#print(getattr(d,choice))

#getattr(d,choice)()

if hasattr(d,choice):
func = getattr(d,choice)
func("piza")

else:
# setattr(d,choice,bulk)
#
# d.talk(d)

setattr(d,choice,22)
print(getattr(d,choice))


输出结果





二、异常处理

1、定义:

python的运行时错误称作异常
语法错误
逻辑错误
2、python异常是一个对象,表示错误或意外情况

3、python检测到一个错误时,将触发异常
4、可理解为:当程序出现了错误而在正常控制流以外采取的行为

第一阶段:解释器触发异常,此时当前程序将被打断
第二阶段:异常处理,如忽略非致命错误,减轻错误带来的影响等
5、异常的功用

错误处理
事件通知
特殊情况处理
终止行为
非常规控制流程
6、异常的检测和处理

异常通过try语句来检测(try-except, try-finally)
try语句的复合形式(try-except-finally)
try-except-else-finally语句
7、异常的种类
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的

ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError


8、自定义异常

raise语句可显示触发异常
raise [SomeException[,args[,traceback]]]

class WupeiqiException(Exception):

def __init__(self, msg):
self.message = msg

def __str__(self):
return self.message

try:
raise WupeiqiException('我的异常')
except WupeiqiException,e:
print e
class AlexError(Exception):
def __init__(self, msg):
self.message = msg
# def __str__(self):
#     return 'sdfsf'
try:
raise AlexError('数据库连不上')
except AlexError as e:
print(e)


输出结果



raise语句的用法大全
raise exclass
raise exclass()
raise exclass,args
raise exclass(args)
raise string,args


9、assert(断言)

用于在程序中引入调试代码
若运行python时使用-O优化选项,则assert将是一个空操作,若不用-O选项,则_debug_内置变量为T如额,否则为False
assert实现:手动触发异常
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: