STCX

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

异常管理


 

# coding=utf-8

# 自定义异常
class HappyException(Exception):
    pass

# 引发和捕获异常
try:
    raise HappyException
except:
    print("HappyException")

try:
    raise HappyException()
except:
    print("HappyException")

# 捕获多种异常
try:
    raise HappyException
except (HappyException, TypeError):
    print("HappyException")

# 重新引发异常
try:
    try:
        raise HappyException
    except (HappyException, TypeError):
        raise
except:
    print("HappyException")

#访问异常实例
try:
    raise HappyException("都是我的错")
except (HappyException, TypeError), e:
    print(e)

#按类型捕获
try:
    raise HappyException
except HappyException:
    print("HappyException")
except TypeError:
    print("TypeError")

#全面捕获
try:
    raise HappyException
except:
    print("HappyException")

#没有异常的else
try:
    pass
except:
    print("HappyException")
else:
    print("没有异常")

#总会执行的final
try:
    pass
except:
    print("HappyException")
else:
    print("没有异常")
finally:
    print("总会执行")

 

面向对象


 

先上一张图

 

 

几个规则:

 

  1. 一切都是对象,python中一切都是对象,每个对象都包含一个__class__属性以标记其所属类型。

  2. 每个对象(记得一切都是对象啊)都包含一个__dict__属性以存储所有属性和方法。

  3. 每个类型都包含一个__bases__属性以标记其父类。

  4. 属性和方法的访问规则:依次搜索instance、子类、父类、父类的父类、直到object的__dict__,如果找到就返回。

  5. 属性和方法的设置规则:直接设置instance.__dict__。

  6. 以上属性和方法访问或设置规则没有考虑“魔法方法”,下文会解释。

 

示例

 

# coding=utf-8

__metaclass__ = type

# 类型定义
# 实例方法必的第一个参数代表类型实例,类似其他语言的this。
class Animal:
    name = "未知" # 属性定义。

    def __init__(self, name): #构造方法定义。
        self.name = name

    def getName(self): # 实例方法定义。
        return self.name

    def setName(self, value):
        self.name = value

print(Animal.name) # 未知
print(Animal.__dict__["name"]) # 未知

animal = Animal("狗狗")
print(animal.name) # 狗狗
print(animal.__dict__["name"]) # 狗狗
print(Animal.name) # 未知
print(Animal.__dict__["name"]) # 未知
print(animal.__class__.name) # 未知
print(animal.__class__.__dict__["name"]) # 未知

 

1 # 类型定义中的代码会执行,是一个独立的作用域。

2 class TestClass:

3  print("类型定义中") #类型定义中

 

绑定方法和未绑定方法

 

class TestClass:
    def method(self):
        print("测试方法")

test = TestClass()
print(TestClass.method) #<unbound method TestClass.method>
print(test.method) #<bound method TestClass.method of <__main__.TestClass object at 0x021B46D0>>

TestClass.method(test) #测试方法
test.method() #测试方法

 

绑定方法已经绑定了对象示例,调用的时刻不用也不能传入self参数了。

注:使用对象访问实例方法为何会返回绑定方法?这个还得等到学完“魔法方法”才能解释,内部其实是拦截对方法成员的访问,返回了一个Callable对象。

 

私有成员

 

# 私有成员
class TestClass:
    __private_property = 1

    def __private_method():
        pass

print(TestClass.__dict__) # {'__module__': '__main__', '_TestClass__private_method': <function __private_method at 0x0212B970>, '_TestClass__private_property': 1

 

难怪访问不了了,名称已经被修改了,增加了访问的难度而已。

 

多重继承

 

#多重继承
class Base1:
    pass

class Base2:
    pass

class Child(Base2, Base1):
    pass

child = Child()
print(isinstance(child, Child)) # True
print(isinstance(child, Base2)) # True
print(isinstance(child, Base1)) # True

 

如果继承的多个类型之间有重名的成员,左侧的基类优先级要高,上例子Base2会胜出。

 

接口那里去了,鸭子类型比接口更好用。

 

class TestClass1:
    def say(self):
        print("我是鸭子1")

class TestClass2:
    def say(self):
        print("我是鸭子2")

def duck_say(duck):
    duck.say()

duck_say(TestClass1()) # 我是鸭子1
duck_say(TestClass2()) # 我是鸭子2

 

调用父类

 

# 调用父类
class Base:
    def say(self):
        print("Base")

class Child(Base):
    def say(self):
        Base.say(self)
        super(Child, self).say()
        print("Child")

child = Child()
child.say()

 

魔法方法


 

详细内容参考:http://www.rafekettler.com/magicmethods.html

对象构造相关:__new__、__init__、__del__。

 

from os.path import join

class FileObject:
    '''Wrapper for file objects to make sure the file gets closed on deletion.'''

    def __init__(self, filepath='~', filename='sample.txt'):
        # open a file filename in filepath in read and write mode
        self.file = open(join(filepath, filename), 'r+')

    def __del__(self):
        self.file.close()
        del self.file

 

运算符重载:所有运算符都能重载。

 

class Word(str):
    '''Class for words, defining comparison based on word length.'''

    def __new__(cls, word):
        # Note that we have to use __new__. This is because str is an immutable
        # type, so we have to initialize it early (at creation)
        if ' ' in word:
            print "Value contains spaces. Truncating to first space."
            word = word[:word.index(' ')] # Word is now all chars before first space
        return str.__new__(cls, word)

    def __gt__(self, other):
        return len(self) > len(other)

    def __lt__(self, other):
        return len(self) < len(other)

    def __ge__(self, other):
        return len(self) >= len(other)

    def __le__(self, other):
        return len(self) <= len(other)

print(Word("duan") > Word("wei"))

 

属性访问。


class AccessCounter:
    '''A class that contains a value and implements an access counter.
    The counter increments each time the value is changed.'''

    def __init__(self, value):
        super(AccessCounter, self).__setattr__('counter', 0)
        super(AccessCounter, self).__setattr__('value', value)

    def __setattr__(self, name, value):
        if name == 'value':
            super(AccessCounter, self).__setattr__('counter', self.counter + 1)
        # Make this unconditional.
        # If you want to prevent other attributes to be set, raise AttributeError(name)
        super(AccessCounter, self).__setattr__(name, value)

    def __delattr__(self, name):
        if name == 'value':
            super(AccessCounter, self).__setattr__('counter', self.counter + 1)
        super(AccessCounter, self).__delattr__(name)

 

集合实现。

 

class FunctionalList:
    '''A class wrapping a list with some extra functional magic, like head,
    tail, init, last, drop, and take.'''

    def __init__(self, values=None):
        if values is None:
            self.values = []
        else:
            self.values = values

    def __len__(self):
        return len(self.values)

    def __getitem__(self, key):
        # if key is of invalid type or value, the list values will raise the error
        return self.values[key]

    def __setitem__(self, key, value):
        self.values[key] = value

    def __delitem__(self, key):
        del self.values[key]

    def __iter__(self):
        return iter(self.values)

    def __reversed__(self):
        return FunctionalList(reversed(self.values))

    def append(self, value):
        self.values.append(value)
    def head(self):
        # get the first element
        return self.values[0]
    def tail(self):
        # get all elements after the first
        return self.values[1:]
    def init(self):
        # get elements up to the last
        return self.values[:-1]
    def last(self):
        # get last element
        return self.values[-1]
    def drop(self, n):
        # get all elements except first n
        return self.values[n:]
    def take(self, n):
        # get first n elements
        return self.values[:n]

 

可调用对象,像方法一样调用对象。

 

class Entity:
    '''Class to represent an entity. Callable to update the entity's position.'''

    def __init__(self, size, x, y):
        self.x, self.y = x, y
        self.size = size

    def __call__(self, x, y):
        '''Change the position of the entity.'''
        self.x, self.y = x, y
        print(x, y)

entity = Entity(5, 1, 1)
entity(2, 2)

 

资源管理

 

class Closer:
    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_val, trace):
        print("清理完成")
        return True;

with Closer() as closer:
    pass

 

对象描述符。

 

class Meter(object):
    '''Descriptor for a meter.'''

    def __init__(self, value=0.0):
        self.value = float(value)
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)

class Foot(object):
    '''Descriptor for a foot.'''

    def __get__(self, instance, owner):
        return instance.meter * 3.2808
    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808

class Distance(object):
    '''Class to represent distance holding two descriptors for feet and
    meters.'''
    meter = Meter()
    foot = Foot()

 

Mixin(也叫掺入)


 

掺入模块:playable.py

 

1 # coding=utf-8

2

3 def paly(self):

4  print("游戏中...")

 

掺入目标模块:test.py

 

# coding=utf-8

class Animal:
    from playable import paly

animal = Animal()
animal.paly() # 游戏中...

 

Open Class(打开类型,从新定义成员)


 

#coding:utf-8

class TestClass:
    def method1(self):
        print("方法1")

def method2(self):
    print("方法2")

TestClass.method2 = method2

test = TestClass()
test.method1() # 方法1
test.method2() # 方法2

 

Meta Programming(元编程)


 

TestClass = type("TestClass", (object,), {
    "say": lambda self : print("你好啊")
})

test = TestClass()
test.say()


def getter(name):
    def getterMethod(self):
        return self.__getattribute__(name)
    return getterMethod

def setter(name):
    def setterMethod(self, value):
        self.__setattr__(name, value)
    return setterMethod    

class TestClass:
    getName = getter("name")
    setName = setter("name")

test = TestClass()
test.setName("段光伟")
print(test.getName())

 

AOP(面向切面编程)


 

内容比较多,单独写了一篇文章:http://www.cnblogs.com/happyframework/p/3260233.html

 

备注


 

Python在作用域方面非常接近Javascript,类型和对象系统也有几份相似(虽然Javascript是基于原型的),Javascript、PHP、Python和Ruby这几门语言交叉学习会带来意想不到的收获。

 

框架地址:http://happy.codeplex.com
博客地址:http://www.cnblogs.com/happyframework

 

出自:博客园

原创作者:幸福框架

 

原链接:http://mp.weixin.qq.com/s?__biz=MjM5MTYxNjQxOA==&mid=2652841239&idx=1&sn=44c9106f4b5994072861e9d33a406ab3&chksm=bd5959da8a2ed0cc413ab99df2efd3516d7e24c49d0b4b11291be51a47d73c8b379b24f506fd&mpshare=1&scene=23&srcid=0327Vd0OWFlbHQ1WN6ySZU0M#rd

posted on 2018-03-27 19:29  STCX  阅读(108)  评论(0)    收藏  举报