静态方法:
@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("\033[31;1mHas changed the flight status to \033[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