Sah*_*and 0 python oop methods function
我正在编写一个程序来检查给定的密码是否至少包含1个大写字母和1个小写字母.我可以很容易地检查这样:
#Password needs to have at least 1 upper case letter
has_upper_letter = False
for letter in password:
if letter.isupper():
has_upper_letter = True
break
if not has_upper_letter:
raise forms.ValidationError(_("The password needs to have at least 1 upper case letter"))
#Password needs to have at least 1 lower case letter
has_lower_letter = False
for letter in password:
if letter.islower():
has_lower_letter = True
break
if not has_lower_letter:
raise forms.ValidationError(_("The password needs to have at least 1 lower case letter"))
Run Code Online (Sandbox Code Playgroud)
但是这段代码是重复的.我想只在一次检查某种字母的字母时编写逻辑.我的想法是编写一个以isupper()或islower()函数作为参数的函数.但问题是,isupper()和islower()方法作为字符串本身的方法存在.如果我只能得到一个函数,它将我想要检查的字符串作为其参数,我的问题将得到解决.有这样的事吗?随意为我的问题发布更好的解决方案.
你可以使用operator.methodcaller(),或者你可以使用getattr(); 要么可以用来动态调用方法:
from operator import methodcaller
def matches_test(test, password):
return any(map(test, password))
has_lower_letter = matches_test(methodcaller('islower'), password)
has_upper_letter = matches_test(methodcaller('isupper'), password)
Run Code Online (Sandbox Code Playgroud)
methodcaller() 在传递给它的任何内容上调用named方法:
>>> from operator import methodcaller
>>> upper = methodcaller('isupper')
>>> upper('ABC')
True
>>> upper('abc')
False
Run Code Online (Sandbox Code Playgroud)
methodcaller()对象也接受传入的其他参数,因此methodcaller('foo', 42)会调用.foo(42)传递给它的任何对象.
该any()函数只是一种(更紧凑)for用iftest 编写循环的方法break; 它遍历你传入的迭代,并停止True产生结果的那一刻; 如果没有True产生任何结果,False则返回.
getattr()让您访问变量属性; 方法只是你调用的属性:
def matches_test(methodname, password):
return any(getattr(l, methodname)() for l in password)
has_lower_letter = matches_test('islower', password)
has_upper_letter = matches_test('isupper', password)
Run Code Online (Sandbox Code Playgroud)
你也可以传入一个未绑定的字符串方法,所以str.isupper或str.islower; 传入一个新的字符串值就像将该方法绑定到该字符串:
>>> str.isupper('ABC')
True
Run Code Online (Sandbox Code Playgroud)
所以以下也有效:
def matches_test(test, password):
return any(test(l) for l in password)
has_lower_letter = matches_test(str.islower, password)
has_upper_letter = matches_test(str.isupper, password)
Run Code Online (Sandbox Code Playgroud)