这是我的一段代码,定义了两个生成器:
let imagePicker: UIImagePickerController! = UIImagePickerController()
let saveFileName = "/test.mp4"
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
if UIImagePickerController.availableCaptureModes(for: .rear) != nil {
//if the camera is available, and if the rear camera is available, the let the image picker do this
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeMovie as String]
imagePicker.allowsEditing = false
imagePicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
imagePicker.videoMaximumDuration = 60
imagePicker.videoQuality = .typeIFrame1280x720
present(imagePicker, animated: true, completion: nil)
} else {
postAlert("Rear camera doesn't exist", message: "Application cannot access the camera.")
}
} else {
postAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
print(123)
imagePickerController(imagePicker, didFinishPickingMediaWithInfo: [saveFileName : kUTTypeMovie])
let videoURL = info[UIImagePickerControllerReferenceURL] as? NSURL
print("\(String(describing: videoURL))" )
guard let path = videoURL?.path else { return }
let videoName = path.lastPathComponent
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentDirectory = paths.first as String!
let localPath = documentDirectory! + "/" + videoName
guard let imageData = NSData(contentsOfFile: localPath) else { return }
let image = UIImage(data: imageData as Data)
picker.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.imagePicker.delegate = self
}
执行时:
one_line_gen = (x for x in range(3))
def three_line_gen():
yield 0
yield 1
yield 2
结果如预期:
for x in one_line_gen:
print x
for x in one_line_gen:
print x
但是,如果我执行:
0
1
2
结果是:
for x in three_line_gen():
print x
for x in three_line_gen():
print x
为什么呢?我以为任何发电机只能使用一次。
答案 0 :(得分:12)
XElement
不是生成器,它是一个函数。当你打电话给它时它返回的是一个发电机,每次调用它时都是一个全新的发电机。每次你像这样放括号:
var comments = xml.Root.NodesAfterSelf().OfType<XComment>();
这是一个值得迭代的全新生成器。但是,如果你是第一次做
three_line_gen
并迭代three_line_gen()
两次,第二次将按预期失败。
答案 1 :(得分:3)
不,你不能两次迭代生成器。迭代后,生成器会耗尽。您可以使用tee
创建一个生成器的副本:
from itertools import tee
one_line_gen = (x for x in range(3))
gen1, gen2 = tee(one_line_gen)
# or:
# gen1, gen2 = tee(x for x in range(3))
for item in gen1:
print(item)
for item in gen2:
print(item)
其他问题请参阅Ofer Sadan's answer。
答案 2 :(得分:1)
为什么呢?我以为任何发电机只能使用一次。
因为每次调用 three_line_gen()都会创建一个新的生成器。
否则,你是正确的,发电机只能向前运行直到用尽。
发电机可以多次使用吗?
是的,如果结果在发生器外缓冲,则可能。一种简单的方法是使用itertools.tee():
>>> from itertools import tee
>>> def three_line_gen():
yield 0
yield 1
yield 2
>>> t1, t2 = tee(three_line_gen())
>>> next(t1)
0
>>> next(t2)
0
>>> list(t1)
[1, 2]
>>> list(t2)
[1, 2]
答案 3 :(得分:0)
因为在一个班轮中是mygen = three_line_gen()
对象而三个班轮是mygen
。
他们的意思不同。
这两个是相似的。
Generator
答案 4 :(得分:0)
是的,发电机只能使用一次。但你有两个生成器对象。
# Python 3
def three_line_gen():
yield 0
yield 1
yield 2
iterator = three_line_gen()
print(iterator)
for x in iterator:
print(id(iterator), x)
iterator2 = three_line_gen()
print(iterator2)
for x in iterator2:
print(id(iterator2), x)
结果是:
<generator object three_line_gen at 0x1020401b0>
4328784304 0
4328784304 1
4328784304 2
<generator object three_line_gen at 0x1020401f8>
4328784376 0
4328784376 1
4328784376 2