zoukankan      html  css  js  c++  java
  • 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

    运行结果:

     

  • 相关阅读:
    Mysql登录错误:ERROR 1045 (28000): Plugin caching_sha2_password could not be loaded
    Docker配置LNMP环境
    Docker安装mysqli扩展和gd扩展
    Docker常用命令
    Ubuntu常用命令
    单例模式的优缺点和使用场景
    ABP 多租户数据共享
    ABP Core 后台Angular+Ng-Zorro 图片上传
    ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
    AbpCore 执行迁移文件生成数据库报错 Could not find root folder of the web project!
  • 原文地址:https://www.cnblogs.com/platycoden/p/10427085.html
Copyright © 2011-2022 走看看