我正在尝试根据传入的参数更改函数的行为。我正在考虑使用if语句,但我真的不想这样做。 例如:
def BigPrime(numP, plist = [], x = 1, counter =0):
while len(plist) <= numP:
if x == 1 or x == 2 or x == 5:
plist.append(x)
elif x % 2 is not 0 and int(str(x)[-1]) is not 5:
for div in plist[1:]:
#Non mettere niente qui, strane magie
#accadono in questo luogo...
if x % div == 0:
break
else:
plist.append(x)
counter += 1
x += 1
return plist, counter
编辑:好的,因为这个例子没有很多我提出真正的功能。对困惑感到抱歉!欢迎任何建议!
我需要这样的东西:
def foo(arg = 0, x = 0):
if not arg:
while True:
pass
else:
while x < arg:
print('bar')
x+=1
这真的很可怕, 这真的是唯一的方法吗?是不是有更优雅的工作?
答案 0 :(得分:1)
由于您的函数foo
的行为在两种情况下完全无关,因此我认为if
没有任何问题。
由于您决定避免使用if
语句,因此您可以定义两个函数,并在其中选择其他任何方式:
def foo(arg = 0, x = 0):
def loop_forever():
while True:
pass
def print_stuff():
while x < 100:
print('bar')
x += 1
# now, any of these:
# if expression not if statement!
print_stuff() if arg else loop_forever()
# what people did before the if expression
# *but* you have to change print_stuff to return a true value
arg and print_stuff() or loop_forever()
# data-driven design, buzzword-compliant ;-)
[loop_forever, print_stuff][bool(arg)]()
一般来说,为此选择一种技术,你要看两种情况之间的相同和不同之处,并决定在此基础上使用哪些抽象。但在这种情况下,两者之间没有任何相同之处。
有一种丑陋的,丑陋的&#34;在这里工作的原则:基本上没有办法表达两个不相关的操作,除了在两个不同的地方分别编写它们。无论是将这些位置分隔为if
的子句,还是作为两个不同的函数,或者将两个不同的类与多态相区分,如果代码中只有一个点负责定义它们,则几乎无关紧要,在它们之间进行选择,并执行一个。如果这三件事情是在不同的地方完成的,那么你就要做出重大决定。
对于您的真实代码,这就是我认为我写的东西,以及它的价值。完全有可能我已经介绍了一个错误,但我不认为这么多代码我想要编写更多功能。我没有声称理解代码的目的,因为,就像3是素数,但我相信以下是等价的:
def BigPrime(numP, plist = [], x = 1, counter =0):
while len(plist) <= numP:
if x in (1, 2, 5):
plist.append(x)
elif x % 2 != 0 and x % 5 != 0
if all(x % div != 0 for div in plist[1:]):
plist.append(x)
counter += 1
x += 1
return plist, counter
可能的优化,plist[1:]
复制数组,因此itertools.islice(plist, 1, None)
可能会更好。
答案 1 :(得分:1)
恕我直言,需要此功能表明可能是糟糕的设计。通常,一个函数应该实现一个明确的目标。如果需要两种不同的行为,则应将其实现为过于不同的功能。
def block_script():
while True:
pass
def wait_and_spam(x = 0):
while x < 100:
print('bar')
x+=1
一个函数可以使用不同的参数集实现相同的目标。在这种情况下,通常可以首先检查参数以使用默认值填充缺失的参数,根据参数准备数据,然后运行相同的算法。对于静态类型语言有一种特殊情况,其中算法本身的实现必须根据参数的类型进行更改,然后重载是一个很好的特性。但事实并非如此。
/* Add two values with protection against overflow (short) */
unsigned short secure_add(unsigned short a, unsigned short b) {
unsigned long result = (unsigned long)a + (unsigned long)b;
if (result > (unsigned long)0xFFFF) {
return (unsigned short)0xFFFF;
} else {
return (unsigned short) result;
}
}
/* Add two values with protection against overflow (char) */
unsigned char secure_add(unsigned char a, unsigned char b) {
unsigned short result = (unsigned short)a + (unsigned short)b;
if (result > (unsigned short)0xFF) {
return (unsigned char)0xFF;
} else {
return (unsigned char) result;
}
}
最后,Python提供了像getattr
这样的功能,允许根据名称获取对函数的引用。该名称可以在运行时构建。
class Parser:
def parse(self, source, initpos = 0):
for token in self.lexer.get_tokens(source, initpos):
# Call the state handler
statemgr = getattr(self, "_s_"+self.state)
statemgr(token)
def _s_func_header(self, token):
if token.name == "parenthesis_open":
self.state = "function_arguments"
# ...
def _s_function_arguments(self, token):
# ...
答案 2 :(得分:0)
您可以使用功能列表或词典:
def foo_0(x):
while True:
pass
def foo_1(x):
while x < 100:
print('bar')
x += 1
def foo_list(arg=0, x=0):
[foo_0, foo_1][arg](x)
def foo_dict(arg=0, x=0):
{0: foo_0, 1: foo_1}[arg](x)
如果您的arg可以在[0,1]之外,则需要在索引列表或词典之前对其进行约束。