【问题标题】:How to pass function name of child class as parameter to parent class method in python?如何将子类的函数名作为参数传递给python中的父类方法?
【发布时间】:2015-10-06 08:19:30
【问题描述】:
from datetime import datetime
import time

class Base(object):
    def __init__(self):
        pass

    def storeResult(self, function_name, result, executed_time= None):
        pass  # store result in nested dictinary



class Derived(Base):

    def __init__(self):
         pass

    def sum(self, a, b):
        print 'In derived!'
        a = 0
        b = 0
        result = a + b
        super(Base, self).storeResult("sum", result, str(datetime.now())) # Don't want to pass string,Is there any pythonic way of passing function name

    def diff(self, a, b):
        print 'In derived!'
        result = a - b
        super(Base, self).storeResult("diff", result, str(datetime.now())) # Don't want to pass string, Is there any pythonic way of passing function name

    def multiply(self, a, b):
        print 'In derived!'
        a = 0
        b = 0
        result = a * b
        super(Base, self).storeResult("multiply", result, str(datetime.now())) # Don't want to pass string, Is there any pythonic way of passing function name

    def divide(self, a, b):
        print 'In derived!'
        a = 0
        b = 0
        result = a / b
        super(Base, self).storeResult("divide", result, str(datetime.now())) # Don't want to pass string,  Is there any pythonic way of passing function name


if __name__ == '__main__':
    d = Derived()
    d.sum(1,2)
    d.diff(2,1)
    d.multiply(1,2)
    d.divide(10,5)
    d.sum(1,12)
    d.diff(12,1)
    d.multiply(11,2)
    d.divide(10,15)
    d.sum(11,12)
    d.diff(12,1)
    d.multiply(11,2)
    d.divide(110,5)

我面临以下问题:

1) 我想从子类调用父类方法: 第 79 行,总和 :: super(Base, self).storeResult("sum", result, str(datetime.now())) AttributeError: 'super' 对象没有属性 'storeResult'

2) 如何以pythonic方式将子类的函数名作为参数传递给父类方法?

3)我想确保在派生类的每个函数调用之后,将每个结果和函数名称以及在基类 storeResult 中执行的时间存储在嵌套字典中,例如 { function:{result:time}} 。

我对 python 有点陌生,在此先感谢。

【问题讨论】:

    标签: python


    【解决方案1】:

    使用 decorator 函数来包装被调用的方法。

    from collections import defaultdict
    from datetime import datetime
    from functools import wraps
    
    
    def store_result(method):
        @wraps(method)
        def wrapped(self, *args, **kwargs):
            result = method(self, *args, **kwargs)
            self.storeResult(method.__name__, result, str(datetime.now()))
            return result
    
        return wrapped
    
    
    class Base(object):
        def __init__(self):
            self.results = defaultdict(dict)
    
        def storeResult(self, function_name, result, executed_time= None):
            self.results[function_name][result] = executed_time
    
    
    class Derived(Base):
        @store_result
        def sum(self, a, b):
            print 'In derived!'
            a = 0
            b = 0
            return a + b
    
        @store_result
        def diff(self, a, b):
            print 'In derived!'
            return a - b
    
        @store_result
        def multiply(self, a, b):
            print 'In derived!'
            a = 0
            b = 0
            return a * b
    
        @store_result
        def divide(self, a, b):
            print 'In derived!'
            a = 0
            b = 0
            return a / b
    

    我使用defaultdict 来存储结果 - 它允许在分配值时传递一个工厂函数来处理丢失的键。

    【讨论】:

    • 非常感谢您的快速回复!您能否在派生类的每个函数调用之后告诉我,将每个结果和函数名称以及在基类 storeResult 中执行的时间存储在嵌套字典中,例如 { function:{result:time}} 。我是蟒蛇的新手。请对此提供帮助
    • 包装的方法已经用正确的参数调用了storeResult。您需要做的就是在Base 类的__init__ 方法中创建一个字典,以便它的所有实例都有单独的字典。然后,在storeResult 中,只需为该字典分配正确的值。
    • 能否编辑一下你的答案,初学者理解起来有点困难。
    • 太好了!!我有两个基本问题我有基类和子类是不同的文件。 store_result(method):这个函数是在基类文件还是子类文件中?如果我这样做 d = Derived() d.sum(1,2) d.diff(2,1),它会自动包装到父类吗?提前致谢
    • 你在定义它们的地方装饰方法。装饰基本上是method_name = store_result(method) 的语法糖。如果你在Base 中装饰了一个方法,并且没有在Derived 中覆盖它,那么当从Derived 内部调用该方法时,将调用该装饰方法。这里没有魔法。
    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多