静态方法:
@staticmethod 实际上,静态方法与类没有实质上的关系,相当于类的一个工具包
类方法:
@classmethod 只能访问类变量,不能访问示例变量
属性方法:
@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("删除") d = Dog("小熊") d.eat = "包子" del d.eat d.eat #已删除,会报错
属性方法的使用场景:
假设我们做一个航班的类,实例化的过程中会赋予对象一些属性,那么航班状态这个属性是随着时间变化实时更新的,这种情况下,使用静态属性明显得不到我们想要实现的功能,所以这种场景可以使用属性方法。每一次调用对象属性,都会去执行属性方法,获得当前最新的状态。
定义航班类:
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("CA980") f.flight_status 航班查询
现在定义好了类,那就实例化看下:
f = Flight("CA980") f.flight_status f.flight_status = 2 ---------输出:------------------- checking flight CA980 status flight is arrived... Traceback (most recent call last): File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 58, in <module> f.flight_status = 2 AttributeError: can't set attribute
报错了,说不能更改属性值,那怎么办呢?可以通过@proerty.setter装饰器在装饰一下,需要写个新方法:
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") @flight_status.setter #修改 def flight_status(self,status): status_dic = { : "canceled", :"arrived", : "departured" } print(" 33[31;1mHas changed the flight status to 33[0m",status_dic.get(status) ) @flight_status.deleter #删除 def flight_status(self): print("status got removed...") f = Flight("CA980") f.flight_status f.flight_status = 2 #触发@flight_status.setter del f.flight_status #触发@flight_status.deleter
上面还写了一个@flight_status.deleter,是允许可以将这个属性删除
类的特殊成员方法:
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__对象后面加括号,触发执行
注:构造方法执行的是由对象触发的,即:对象=类名(),而对__call__方法执行的是由对象后加括号触发的,即对象()或者类()
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 'alex li' obj = Foo() print obj # 输出:alex li
8.__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']
9.__new__\__metaclass__
class Foo(object): def __init__(self,name): self.name = name f = Foo("alex")
上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。
如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
print type(f) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建 print type(Foo) # 输出:<type 'type'> 表示,Foo类对象由 type 类创建
所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。
那么,创建类就可以有两种方式:
a). 普通方式
class Foo(object): def func(self): print('hello alex')
b). 特殊方式
def func(self): print 'hello wupeiqi' Foo = type('Foo',(object,), {'func': func}) #type第一个参数:类名 #type第二个参数:当前类的基类 #type第三个参数:类的成员
def func(self): print("hello %s"%self.name) def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo',(object,),{'func':func,'__init__':__init__}) f = Foo("jack",22) f.func() 加上构造方法
So ,孩子记住,类 是由 type 类实例化产生
那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?
答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程
#_*_coding:utf-8_*_ class MyType(type): def __init__(self, child_cls, bases=None, dict=None): print("--MyType init---", child_cls,bases,dict) #super(MyType, self).__init__(child_cls, bases, dict) # def __new__(cls, *args, **kwargs): # print("in mytype new:",cls,args,kwargs) # type.__new__(cls) def __call__(self, *args, **kwargs): print("in mytype call:", self,args,kwargs) obj = self.__new__(self,args,kwargs) self.__init__(obj,*args,**kwargs) class Foo(object,metaclass=MyType): #in python3 #__metaclass__ = MyType #in python2 def __init__(self, name): self.name = name print("Foo ---init__") def __new__(cls, *args, **kwargs): print("Foo --new--") return object.__new__(cls) def __call__(self, *args, **kwargs): print("Foo --call--",args,kwargs) # 第一阶段:解释器从上到下执行代码创建Foo类 # 第二阶段:通过Foo类创建obj对象 obj = Foo("Alex") #print(obj.name) 自定义元类
类的生成 调用 顺序依次是 __new__ --> __call__ --> __init__
metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好
反射:
通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. """ pass getattr(object, name, default=None)
判断object中有没有一个name字符串对应的方法或属性
def setattr(x, y, v): # real signature unknown; restored from __doc__ """ Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v''
def delattr(x, y): # real signature unknown; restored from __doc__ """ Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y'' """ delattr(x, y)
class Foo(object): def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' obj = Foo() # #### 检查是否含有成员 #### 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') 反射代码示例
import importlib __import__('import_lib.metaclass') #这是解释器自己内部用的 #importlib.import_module('import_lib.metaclass') #与上面这句效果一样,官方建议用这个
异常处理
#异常: try: code except (Error1,Error2)as e: print e except Exception #抓住所有错误,一般不建议用 #捕获字典错误 data = {} try: data['name'] except KeyError as e: print("没有这个KEY",e) #捕获列表错误 names = ['tim','alex'] try: names[3] except IndexError as e: print("没有这个索引值!",e) #合起来 data = {} names = ['tim','alex'] try: names[3] data['name'] except KeyError as e: print("没有这个key",e) except IndexError as e: print("列表操作错误",e) #当两种错误出现时,都采用同一处理办法时,可以这么写 data = {} names = ['tim','alex'] try: names[3] data['name'] except (KeyError,IndexError) as e: print("没有这个key",e) #抓所有错误: data = {} names = ['tim','alex'] try: #names[3] #data['name'] open('tes.txt') except Exception as e: print("出错了",e) #自定义异常 class TimException(Exception): #定义一个异常,继承基类Exception def __init__(self,msg): self.message = msg def __str__(self): return self.message try: raise TimException("数据库连不上") except TimException as e: print(e)
Socket 编程
参考:http://www.cnblogs.com/wupeiqi/articles/5040823.html