在Python中添加一个将字符串转换为小写的修饰符

2024-10-01 17:25:34 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,我对学习decorators是个新手,我已经看过无数的教程,虽然我理解并且基本上可以遵循所有的示例,但我认为学习的最好方法是自己实现一个decorator。所以我要用下面这个例子。我意识到一个decorator根本不需要这样做,但是为了学习,我想添加一个decorator,它过滤像dog name和breed这样的字符串,并将它们转换为小写。任何在正确方向上的想法或建议都将不胜感激。在

class Dogs:
    totalDogs = 0
    dogList=[]

    def __init__(self, breed, color, age):
        self.breed=breed
        self.color=color
        self.age=age
        Dogs.dogList.append(self.breed)
        Dogs.totalDogs += 1

    def displayDogs(self):
        print "breed: ", self.breed
        print "color: ",self.color
        print "age: ",self.age
        print "list of breeds:", Dogs.dogList
        print "total dogs: ", Dogs.totalDogs

def somedecorator(*args):
    #now what

terrier=Dogs("TeRrIer", "white", 5)
terrier.displayDogs()
retriever=Dogs("goldenRETRIEVER", "brown", 10)
retriever.displayDogs()

Tags: selfdecoratorsagedefdecoratorcolorprintdogs
3条回答

为了简化它,我们先来处理函数。假设您有一个函数,它可以打印其参数的某些信息:

def print_info(breed, name):
    print "The doggie %s's breed is %s." % (name, breed)

因此:

^{pr2}$

现在你希望这个函数总是小写。所以你应该理智地这样做:

def manually_lowered_print_info(breed, name):
    print "The doggie %s's breed is %s." % (name, breed.lower())

输出为:

>>> manually_lowered_print_info("Labrador", "Spike")
The doggie Spike's breed is labrador.

但是,假设由于某种原因,您经常需要将您编写的函数的第一个字符串参数小写,所以您想将其抽象为decorator。我们希望它看起来像这样并且有相同的输出:

@lower_first_arg
def dec_lowered_print_info(breed, name):
    print "The doggie %s's breed is %s." % (name, breed)

这只是语法上的甜点:

def tmp_func(breed, name):
    print "The doggie %s's breed is %s." % (name, breed)
dec_lowered_print_info = lower_first_arg(tmp_func)

{{we要返回print_info函数专门定制一个函数。在

def lower_first_arg(print_info_func_arg):
    def inner_print_info(breed, name):
        return print_info_func_arg(breed.lower(), name)
    return inner_print_info

有用吗?让我们看看:

>>> transformed_print_info = lower_first_arg(print_info)
>>> print_info("Pit Bull", "Spot")
The doggie Spot's breed is Pit Bull.
>>> transformed_print_info("Pit Bull", "Spot")
The doggie Spot's breed is pit bull.
太好了!请注意,我们将print_info作为参数传递给lower_first_arg函数,在该函数中,它由局部变量print_info_func_arg引用。在

如果我们使用decorator语法,它的工作原理是相同的:

@lower_first_arg
def dec_lowered_print_info(breed, name):
    print "The doggie %s's breed is %s." % (name, breed)

杰出的:

>>> dec_lowered_print_info("Pit Bull", "Spot")
The doggie Spot's breed is pit bull.

很酷,就这样,真的。现在为了使decorator更通用,让我们首先概括一下这些名称:

def generic_lower_first_arg(f):
    def wrapped(arg1, arg2):
        return f(arg1.lower(), arg2)
    return wrapped

现在的问题是这个decorator只对2个arg的函数起作用。理想情况下,我们希望它能在任何1 arg或更多的函数上工作,例如:

@generic_lower_first_arg
def failed_whatnow(first, last, middle):
    print "%s %s %s" % (first, middle, last)

现在,该代码将运行,但如果尝试调用它,则会出现错误:

>>> failed_whatnow("Bob", "Jones", "The Killer")

Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    failed_whatnow("Bob", "Jones", "The Killer")
TypeError: wrapped() takes exactly 2 arguments (3 given)

怎么回事?好吧,decorator接受failed_whatnow并返回它定义的函数wrapped,但是{}函数只接受两个参数!这里的修复方法是使用varargs语法。通常,传递给包装函数的任何关键字参数也是一个好主意。在

def proper_lower_first_arg(f):
    def wrapped(arg1, *args, **kwargs):
        return f(arg1.lower(), *args, **kwargs)
    return wrapped

现在它可以处理各种功能:

@proper_lower_first_arg
def proper_whatnow(first, last, middle):
    print "%s %s %s" % (first, middle, last)

@proper_lower_first_arg
def multiplyit(mm, n=3):
    return mm * n

证明:

>>> proper_whatnow("Bob", "Jones", "The Killer")
bob The Killer Jones
>>> multiplyit("HaHa.Fool!")
'haha.fool!haha.fool!haha.fool!'
>>> multiplyit("HaHa.Fool!", n=5)
'haha.fool!haha.fool!haha.fool!haha.fool!haha.fool!'

修饰符通常用于修改函数/方法的输入参数或返回值。在

方法Dogs.displayDogs不返回任何数据(除了None),所以说要使字符串小写是没有意义的。哪根弦?只需打印值。所以你应该这样做:

class Dogs:
    totalDogs = 0
    dogList=[]

    def __init__(self, breed, color, age):
        self.breed=breed
        self.color=color
        self.age=age
        Dogs.dogList.append(self.breed)
        Dogs.totalDogs += 1

    def displayDogs(self):
        print "breed: ", self.breed.lower()
        print "color: ",self.color.lower()
        ...

否则,您应该重构代码:

^{pr2}$

你做什么

terrier = Dogs("TeRrIer", "white", 5)
print terrier.getDogs()

decorator实际上只是一个函数,它将一个函数作为参数并返回另一个函数。在

def lower_output(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs).lower()
    return wrapper


class Dogs(object):
    totalDogs = 0
    dogList=[]

    def __init__(self, breed, color, age):
        self.breed=breed
        self.color=color
        self.age=age
        Dogs.dogList.append(self.breed)
        Dogs.totalDogs += 1

    @lower_output
    def get_breed(self):
        return self.breed




>>> terrier=Dogs("TeRrIer", "white", 5)
>>> terrier.get_breed()
terrier

相关问题 更多 >

    热门问题