我正在编写一个程序来检查给定的密码是否至少包含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"))
但是这段代码是重复的。我想只在一次检查某种字母的字母时编写逻辑。我的想法是编写一个以isupper()
或islower()
函数为参数的函数。但问题是,isupper()
和islower()
方法作为字符串本身的方法存在。如果我只能得到将我要检查的字符串作为其参数的函数,我的问题就会得到解决。有这样的事吗?随意为我的问题发布更好的解决方案。
答案 0 :(得分:5)
您可以使用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)
methodcaller()
在传递给它的任何内容上调用命名方法:
>>> from operator import methodcaller
>>> upper = methodcaller('isupper')
>>> upper('ABC')
True
>>> upper('abc')
False
methodcaller()
个对象也接受其他参数传入,因此methodcaller('foo', 42)
会在您传递给它的任何对象上调用.foo(42)
。
any()
function只是一种(更加紧凑)用for
测试和if
编写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)
您还可以传入未绑定字符串方法,因此str.isupper
或str.islower
;传入一个新的字符串值就像将该方法绑定到该字符串:
>>> str.isupper('ABC')
True
所以以下内容也有效:
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)
答案 1 :(得分:0)
您可以传递lambda表达式:
def check_password(password, f):
return any(f(i) for i in password)
print(check_password("theString", lambda x:x.isupper()))
或者,将所需的字符串方法传递给函数:
print(check_password("theString", str.isupper))
输出:
True
答案 2 :(得分:0)
解决此问题的另一种方法是使用正则表达式。以下代码将使用以下规则验证密码:
代码:
import re
def pswd_check(pswd):
m=re.match("(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}$", pswd)
return m!=None
if __name__ == "__main__":
print(pswd_check("testthis"))
print(pswd_check("t3sttHis"))
输出:
False
True