我想有一个可以选择返回或产生结果的函数。 这是一个例子。
def f(option=True):
...
for...:
if option:
yield result
else:
results.append(result)
if not option:
return results
当然,这不起作用,我尝试使用python3,无论我设置什么选项值,我总是得到一个生成器。
据我所知,python检查函数的主体,如果存在yield
,则结果将是生成器。
有没有办法解决这个问题并制作一个可以随意返回或屈服的函数?
答案 0 :(得分:19)
你做不到。 list()
的任何使用都会使该函数成为生成器。
您可以使用def f_wrapper(option=True):
gen = f()
if option:
return gen # return the generator unchanged
return list(gen) # return all values of the generator as a list
来包装函数,以存储生成器在列表对象中生成的所有值并返回:
def f():
yield result
def f_as_list():
return list(f())
但是,一般来说,这是糟糕的设计。不要让你的功能改变这样的行为;坚持一种返回类型(生成器或一个对象)并且不要在两者之间切换。
考虑将其拆分为两个函数:
f()
如果您需要生成器,请使用f_as_list()
;如果您想要列表,请使用list()
。
由于next()
,(和# access elements one by one
gen = f()
one_value = next(gen)
# convert the generator to a list
all_values = list(f())
只能访问生成器的一个值)是内置函数,因此您很少需要使用包装器。只需直接调用这些函数:
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public class SendEmail {
final String senderEmailID = "Sender Email id";
final String senderPassword = "Sender Pass word";
final String emailSMTPserver = "smtp.gmail.com";
final String emailServerPort = "465";
String receiverEmailID = null;
static String emailSubject = "Test Mail";
static String emailBody = ":)";
public SendEmail(String receiverEmailID, String emailSubject, String emailBody)
{
this.receiverEmailID=receiverEmailID;
this.emailSubject=emailSubject;
this.emailBody=emailBody;
Properties props = new Properties();
props.put("mail.smtp.user",senderEmailID);
props.put("mail.smtp.host", emailSMTPserver);
props.put("mail.smtp.port", emailServerPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", emailServerPort);
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
SecurityManager security = System.getSecurityManager();
try
{
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
MimeMessage msg = new MimeMessage(session);
msg.setText(emailBody);
msg.setSubject(emailSubject);
msg.setFrom(new InternetAddress(senderEmailID));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(receiverEmailID));
Transport.send(msg);
System.out.println("Message send Successfully:)");
}
catch (Exception mex)
{
mex.printStackTrace();
}
}
public class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(senderEmailID, senderPassword);
}
}
public static void main(String[] args) {
SendEmail mailSender;
mailSender = new SendEmail("Receiver Email id","Testing Code 2 example","Testing Code Body yess");
}
}
答案 1 :(得分:1)
这个怎么样?
def make_f_or_generator(option):
def f():
return "I am a function."
def g():
yield "I am a generator."
if option:
return f
else:
return g
这至少为您提供了创建函数或生成器的选择。
答案 2 :(得分:0)
class
的方法
class FunctionAndGenerator:
def __init__(self):
self.counter = 0
def __iter__(self):
return self
# You need a variable to indicate if dunder next should return the string or raise StopIteration.
# Raising StopIteration will stop the loop from iterating more.
# You'll have to teach next to raise StopIteration at some point
def __next__(self):
self.counter += 1
if self.counter > 1 :
raise StopIteration
return f"I'm a generator and I've generated {self.counter} times"
def __call__(self):
return "I'm a function"
x = FunctionAndGenerator()
print(x())
for i in x:
print(i)
I'm a function
I'm a generator and I've generated 1 times
[Program finished]