python 面向对象编程进阶
- 创建类和对象的两种方法
- 静态方法 @staticmethod
- 类方法 @classmethod
- 属性方法 @property
- 类的特殊成员方法
- 反射
- 异常处理
- 自定义异常
0.创建类和对象的两种方法
#创建类和对象的第一种方法
class Foo(object):
def __init__(self,name):
self.name = name
f = Foo("baobaohui")
print(type(f))
print(type(Foo))
# 创建类和对象的第二种方法
def func(self):
print("hello %s"%self.name)
def __init__(self,name,age):
self.name = name
self.age = age
Foo= type('Foo',(object,),{'talk':func,'__init__':__init__})
f = Foo("baobaohui",20)
f.talk()
print(type(Foo))
1. 静态方法 @staticmethod
只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性
class Dog(object):
def __init__(self,name):
self.name = name
@staticmethod #静态方法的标志,实际上跟类没什么关系了
def eat(self):
print("%s is eating %s"%(self.name,'dd'))
def talk(self):
print("%s is talking"%self.name)
d = Dog("baobaohui")
d.eat(d)
d.talk()
2. 类方法 @classmethod
只能访问类变量,不能访问实例变量
class Dog(object):
# n = 333
name = "baobaohui"
def __init__(self,name):
self.name = name
#self.n = 333
@classmethod # 类方法 只能访问类变量,不能访问实例变量
def eat(self):
print("%s is eating %s"%(self.name,'dd'))
def talk(self):
print("%s is talking"%self.name)
# d = Dog("baobaohui")
d = Dog("bao")
d.eat()
3. 属性方法 @property
把一个方法变成一个静态属性 d.eat() --> d.eat
class Dog(object):
'''这个类是描述狗这个对象的'''
def __init__(self,name):
self.name = name
self.__food = None
@property # 属性方法标志
def eat(self):
print("%s is eating %s"%(self.name,self.__food))
@eat.setter # 更改属性方法
def eat(self,food):
print("set to food: ",food)
self.__food = food
@eat.deleter #删除属性方法
def eat(self):
del self.__food
print("删完了")
def __call__(self, *args, **kwargs):
print("running call",args,kwargs)
def __str__(self):
return "<obj:%s>" %self.name
print(Dog.__dict__) #打印类里所有的属性,不包括实例属性
d = Dog("baobaohui")
print(d)
d.eat
d.eat = "baozi"
d.eat
del d.eat
4. 类的特殊成员方法
1, __ doc __ 表述类的描述信息
class Foo:
""" 描述类信息,这是用于看片的神奇 """
def func(self):
pass
print Foo.__doc__
#输出:类的描述信息
2, __ module __ 和 __ class __
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
class C:
def __init__(self):
self.name = 'wupeiqi'
----------
from lib.aa import C
obj = C()
print obj.__module__ # 输出 lib.aa,即:输出模块
print obj.__class__ # 输出 lib.aa.C,即:输出类
3, __ init __ 构造方法,通过类创建对象时,自动触发执行
4, __ del __ 析构方法,当对象在内存中被释放时,自动触发执行
5, __ call __ 对象后面加括号,触发执行
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print '__call__'
obj = Foo() # 执行 __init__
obj() # 执行 __call__
6, __ dict __ 查看类或对象中的所有成员
class Province:
country = 'China'
def __init__(self, name, count):
self.name = name
self.count = count
def func(self, *args, **kwargs):
print 'func'
# 获取类的成员,即:静态字段、方法、
print Province.__dict__
# 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
obj1 = Province('HeBei',10000)
print obj1.__dict__
# 获取 对象obj1 的成员
# 输出:{'count': 10000, 'name': 'HeBei'}
obj2 = Province('HeNan', 3888)
print obj2.__dict__
# 获取 对象obj1 的成员
# 输出:{'count': 3888, 'name': 'HeNan'}
7, __ str __ 如果一个类中定义了 str 方法,那么在打印对象时,默认输出该方法的返回值
class Foo:
def __str__(self):
return 'baobaohui'
obj = Foo()
print obj
# 输出:baobaohui
8, getiem,setitem,delitem
用于索引操作,如字典。以上分别表示 获取,设置,删除数据
class Foo(object):
def __init__(self):
self.data = {}
def __getitem__(self, key):
print("__getitem__",key)
return self.data.get(key)
def __setitem__(self, key, value):
print("__setitem__",key,value)
self.data[key] = value
def __delitem__(self, key):
print("__delitem__",key)
# del obj['k2']
obj = Foo()
# print(obj)
obj['name'] = "baobaohui"
print(obj['name'])
print(obj.data)
del obj["baobao"]
result = obj['k1'] #自动触发执行 __getitem__
obj['k2'] = "bao" # 自动触发执行 __setitem__
print(obj.data)
del obj['k2']
print(obj.data)
9, __ new __ \ __ metaclass __
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 init--")
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):
print("Foo __new__")
return object.__new__(cls) # 继承父亲的 __new__ 方法
# 第一阶段:解释器从上到下窒执行代码创建Foo类
# 第二阶段:通过Foo类创建obj对象
obj = Foo("baobaohui")
print(obj.name)
5. 反射
通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
hasattr(object,name)
判断一个对象里是否有对应的name字符串的方法
getattr(object, name, default=None)
根据字符串去获取 obj对象里的对应的方法的内存地址
setattr(x,y,v)
相当于 'x.y = v' 通过字符串设置基本属性
delattr(x,y)
删除对应方法
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("baobaohui")
choice = input(">>:").strip()
if hasattr(d,choice):
getattr(d,choice)("baozi") # 获得 这个方法 并执行
# getattr(d, choice) 获得这个方法的内存地址
# d.eat("baozi")
# delattr(d,choice)
else:
setattr(d,choice,bulk) #d.talk = bulk
func = getattr(d, choice) # 很重要 交互意义上的凸显本质
func(d)
6. 异常处理
names = ['baobaohui','baobao']
try:
open("tes.txt")
except (KeyError,IndexError) as e:
print("没有这个 key")
except IndexError as e:
print("列表操作错误",e)
except BaseException as e:
print("未知错误",e)
except Exception as e:
print("错误",e)
else:
print("一切正常")
finally:
print("不管有没有错,都执行")
7. 自定义异常
class BaoError(Exception):
def __init__(self,msg):
self.message = msg
#
# def __str__(self):
# return '错了'
try:
raise BaoError("数据库连不上")
except BaoError as e:
print(e)