python基础6--面向对象基础、装饰器

 

1、类

class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade
    def introduce(self):
        print("hi! I'm " + self.name)
        print("my grade is: " + str(self.grade))
    def improve(self, amount):
        self.grade = self.grade + amount

jim = Student("jim", 86)
jim.introduce()
jim.improve(10)
jim.introduce()

其中”__init__”内置方法,用于初始化一个类,为构造函数。

self等同于Java中的“this”,代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

2、装饰器

(1)装饰器

'''示例1: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''
 
def deco(func):
    print("before myfunc() called.")
    func()
    print("  after myfunc() called.")
    return func
 
@deco
def myfunc():
    print(" myfunc() called.")
 
myfunc()
myfunc()

运行结果

 

这里有一个问题,就是当我们两次调用myfunc()的时候,发现装饰器函数只被调用了一次。

这里@deco这一句,和myfunc = deco(myfunc)其实是完全等价的,只不过是换了一种写法而已。

将@deco 替换为 myfunc = deco(myfunc),程序首先调用deco(myfunc),得到的返回结果赋值给了myfunc。 (注意:在Python中函数名只是个指向函数首地址的函数指针而已) 
而deco(myfunc)的返回值就是函数myfunc()的地址,这样其实myfunc 没有变化,也就是说,最后的两次myfunc()函数调用,其实都没有执行到deco()。

(2)确保装饰器被调用

'''示例2: 使用内嵌包装函数来确保每次新函数都被调用,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
 
def deco(func):
    def _deco():
        print("before myfunc() called.")
        func()
        print("  after myfunc() called.")
        # 不需要返回func,实际上应返回原函数的返回值
    return _deco
 
@deco
def myfunc():
    print(" myfunc() called.")
    return 'ok'
 
myfunc()
myfunc()

运行结果:

将@deco 替换为 myfunc = deco(myfunc) 
程序首先调用deco(myfunc),得到的返回结果赋值给了myfunc ,这样myfunc 就变成了指向函数_deco()的指针。
以后的myfunc(),其实是调用_deco()。

(3)在内嵌函数前加入语句

'''示例3'''
 
def deco(func):
    print("before _deco.")
    def _deco():
        print("before myfunc() called.")
        func()
        print("  after myfunc() called.")
        # 不需要返回func,实际上应返回原函数的返回值
    return _deco
 
@deco
def myfunc():
    print(" myfunc() called.")
    return 'ok'
 
myfunc()
myfunc()

运行结果:

(4)带参数函数装饰

'''示例4: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''
 
def deco(func):
    def _deco(a, b):
        print("before myfunc() called.")
        ret = func(a, b)
        print("  after myfunc() called. result: %s" % ret)
        return ret
    return _deco
 
@deco
def myfunc(a, b):
    print(" myfunc(%s,%s) called." % (a, b))
    return a + b
 
myfunc(1, 2)
myfunc(5, 6)

运行结果:

(5)装饰器带参数

'''示例5: 装饰器带参数,与之前示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''
 
def deco(arg):
    def _deco(func):
        def __deco():
            print("before %s called [%s]." % (func.__name__, arg))
            func()
            print("  after %s called [%s]." % (func.__name__, arg))
        return __deco
    return _deco
 
@deco("mymodule")
def myfunc():
    print(" myfunc() called.")
 
@deco("module2")
def myfunc2():
    print(" myfunc2() called.")
 
myfunc()
myfunc2()

替换操作 @deco(“mymodule”) 替换为myfunc = deco(“mymodule”)(myfunc ) ,注意deco后面跟了两个括号。 
先执行deco(“mymodule”),返回结果为_deco 
再执行_deco(myfunc),得到的返回结果为__deco 
所以myfunc = __deco

运行结果:

 

 

posted @ 2019-02-26 17:19  platycoden  阅读(185)  评论(0编辑  收藏  举报