title: python语法拾遗(一)
date: 2019-11-12 12:23:49
categories:
- Python
- Python语法相关
tags: - python
- 语法使用
- OOP
description: python面对对象编程(类,继承,多态),错误调试
python面对对象编程(类,继承,多态,鸭子类型)
概念
类(class)与实例(instance) 类是抽象的模板,实例是根据类创建的具体“对象”。实例之间拥有相同的方法,但各自数据可能不同。
__init__
方法,给模板类添加必要的属性。其中,在变量名前添加‘__’双下划线,可以将其变为私有变量,即外部不能随意访问修改。
在类中定义方法,可以保护内部数据,将方法的具体细节隐藏在类内部。
class Studnet(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def get_gender(self):
return self.__name
def set_score(self,score):
if 0 <= score <= 100:
self.__score = score
else:
raise ValueError('bad score')
继承与多态
在定义一个class之后,可以从现有的class继承,新的class称为之类,被继承的类称为父类。子类可以继承父类的全部功能。
多态是指,子类继承父类的方法后,可以自行修改同一方法,覆盖原方法。
鸭子类型:相对于静态语言而言,动态语言要灵活许多。只要含有相同的方法名称,不同继承树的实例,仍都可以执行。
获取对象信息
isinstance
判断数据类型,类(名)也可以看作某种数据类型。
dir()
获取对象的所有方法和属性,返回一个list
hasattr(obj_name,'属性')
判断对象是否含该属性
setattr(obj_name,'属性')
设置新增属性
getattr(obj_name,'属性')
获取属性
使用__slots__
动态的绑定方法和属性
在class定义好后,仍可以在外部,利用MethodType
给类或实例新增方法属性。
class Student(object):
pass
def set_age(self,age): #定义一个方法
self.age = age
from types import MethodType
s = Student()
s.set_age = MethodType(set_age,s) #将指定方法添加到目标实例s
s.set_age(25)
s.age # 该方法仅限该实例s使用。
Student.set_score = set_score # 给类绑定新方法,则其实例将拥有该新方法
限制动态绑定__slots__
__slots__
仅允许类实例动态绑定指定属性名,对类的动态绑定无效。
注意:只对该类实例有效,对类无效,对其继承子类无效。除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
多重继承
通过多重继承,一个子类就可以同时获得多个父类的所有功能。
为了区分继承树主线,一般使用MixIn的设计模式。
class class_name(class1,class2MixIn):
pass
定制类
str__与__repr
当用户直接调用类或实例时,会返回该对象所在的内存地址。
>>> class Student(object):
... def __init__(self, name):
... self.name = name
...
>>> print(Student('Michael'))
# <__main__.Student object at 0x109afb190>
而 __str__
与__repr__
的作用就是设置返回的指定内容。两者的区别是__str__()
返回用户看到的字符串,__repr__()
返回程序开发者看到的字符串,即,__repr__()
是为调试服务的。
class Student(object):
... def __init__(self, name):
... self.name = name
... def __str__(self):
... return 'Student object (name: %s)' % self.name
... __repr__ = __str__
print(Student('Michael'))
# Student object (name: Michael)
错误与调试
try...except...finally
:try
部分用于测试代码执行情况。如果出错就会跳转到except
部分,否则就跳过。执行完成后,如果有finally
语句就继续执行。
此外,如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句
#e.g.
try:
print('try...')
r = 10 / int('2')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print('no error!')
finally:
print('finally...')
print('END')