Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 属性错误:';str';对象没有属性'__模块';_Python_Caching - Fatal编程技术网

Python 属性错误:';str';对象没有属性'__模块';

Python 属性错误:';str';对象没有属性'__模块';,python,caching,Python,Caching,我一直在测试这种缓存方法/代码: 在某些情况下,我会出现以下(或类似)错误: “AttributeError:'str'对象没有属性“模块”” 下面是一些代码示例,这些很好: if __name__ == '__main__': @lru_cacheItem(maxsize=20) def f(x, y): return 3*x+y domain = range(5) from random import choice for i in range(1000): r = f(

我一直在测试这种缓存方法/代码:

在某些情况下,我会出现以下(或类似)错误: “AttributeError:'str'对象没有属性“模块”

下面是一些代码示例,这些很好:

if __name__ == '__main__':
@lru_cacheItem(maxsize=20)
def f(x, y):
    return 3*x+y

domain = range(5)
from random import choice
for i in range(1000):
    r = f(choice(domain), choice(domain))

print('Hits:{0}'.format(f.hits), 'Misses:{0}'.format(f.misses))

@lfu_cacheItem(maxsize=20)
def f(x, y):
    return 3*x+y

domain = range(5)
from random import choice
for i in range(1000):
    r = f(choice(domain), choice(domain))

print('Hits:{0}'.format(f.hits), 'Misses:{0}'.format(f.misses))  


@lru_cacheItem(maxsize=20)
def myString(a, b):
    return '{0} and {1}'.format(a, b)

a = 'crap'
b = 'shit'
for i in range(1000):
    r = myString(a, b)

print('Hits:{0}'.format(myString.hits), 'Misses:{0}'.format(myString.misses)) 
这并不是:

if __name__ == '__main__':    
class P4client(object):
    def __init__(self):
        pass

    def checkFileStats(self, filePath):
        results = 'The filepath: {0}'.format(filePath)
        print results
        return results

p4client = P4client()

filePath = (r"C:\depot\tester.tga")

@lfu_cacheItem            
def p4checkFileStats(filePath):
    '''Will cache the fstats return'''
    p4checkResults = p4client.checkFileStats(filePath)
    return p4checkResults    

p4checkFileStats(filePath)
我不知道如何解决这个问题。。。这似乎是functools中的一个问题,我假设我正在包装的函数中调用一个类/方法

@lfu_cacheItem            
def p4checkFileStats(filePath):
此处缺少括号:

@lfu_cacheItem()            
def p4checkFileStats(filePath):
所有需要“选项”的装饰师,即您可以使用:

@decorator(a=Something, b=Other, ...)
def the_function(...):
装饰时必须始终调用,即使您没有提供参数:

@decorator()
def the_function(...):

你为什么想知道?首先,请记住装饰器是接受函数作为参数的普通函数:

In [1]: def hooray(func):
   ...:     print("I'm decorating function: {.__name__}".format(func))
   ...:     return func

In [2]: @hooray
   ...: def my_function(): pass
I'm decorating function: my_function
正如您所看到的,
hooray
被调用。事实上,这就是使用装饰器时实际发生的情况:

In [3]: def my_function(): pass
   ...: my_function = hooray(my_function)
   ...: 
I'm decorating function: my_function
def my_function(): pass
my_function = lfu_cache(my_function)
现在,如果要将选项传递给decorator,可以创建一个返回decorator的函数。这正是您链接的配方中的
lfu\u缓存发生的情况:

def lfu_cache(maxsize=100):
    # ...
    def decorating_function(user_function):
        # ...
    return decorating_function
现在您可以看到,
lfu\u cache
实际上是一个函数。此函数创建一个装饰器,名为
decorating\u function
,并返回它。这意味着呼叫时:

@lfu_cache(maxsize=20)
def my_function(): pass
情况就是这样:

def my_function(): pass
decorator = lfu_cache(maxsize=20)
my_function = decorator(my_function)
如您所见,首先调用了
lfu\u缓存
,并返回一个decorator。然后调用decorator来修饰函数。 如果忘记了括号会发生什么?这意味着什么:

@lfu_cache
def my_function(): pass
是吗

非常简单,它使用
lfu\u缓存
作为一个简单的装饰器:

In [3]: def my_function(): pass
   ...: my_function = hooray(my_function)
   ...: 
I'm decorating function: my_function
def my_function(): pass
my_function = lfu_cache(my_function)
但这很糟糕!您将函数作为
maxsize
参数传递,而
lfu\u cache
返回的值是以前的
decorating\u函数

要了解更多关于装饰师的信息,请阅读下面的答案