如何为Python生成器的send方法创建弱引用?
How to Create a Weak Reference to a Generator's
send Method Without Wrapping the Generator Great question—this is a super tricky edge case with Python's weak references and built-in generator methods! Let's break down why your initial attempts didn't work, then walk through a clean solution that avoids wrapping the generator in a custom class.
Why Your First Tries Failed
- When you use
weakref.ref(g.send), you're trying to reference a temporary built-in method object created on the fly when you accessg.send. These temporary objects don't have a persistent reference, so the weak reference immediately resolves toNone. weakref.WeakMethodis designed exclusively for bound methods of user-defined classes, not built-in methods like a generator'ssend. That's why you hit the type error—it doesn't recognize the generator'ssendmethod as a valid bound method.
The Solution: Weak Reference the Generator Itself
Instead of targeting the send method directly, create a weak reference to the generator instance. Whenever you need to call send, first retrieve the generator from the weak reference (checking if it's still alive) and invoke send on the live instance.
Here's a working example tailored to your message protocol use case:
import weakref def message_processor_generator(): while True: incoming_msg = yield # Example message handling logic print(f"Processing message: {incoming_msg}") # Initialize and prime the generator gen = message_processor_generator() next(gen) # Create a weak reference to the generator, not its send method gen_weak_ref = weakref.ref(gen) def send_message(msg): # Retrieve the generator from the weak reference live_gen = gen_weak_ref() if live_gen is not None: live_gen.send(msg) else: # Handle cleanup if the generator was garbage collected print("Generator no longer exists—message discarded") # Test sending messages send_message("JOIN: user_456") # Output: Processing message: JOIN: user_456 send_message("MESSAGE: hello there") # Output: Processing message: MESSAGE: hello there # Simulate generator being garbage collected del gen send_message("LEAVE: user_456") # Output: Generator no longer exists—message discarded
Why This Works
- Generators are regular Python objects that support weak references, so
weakref.ref(gen)works reliably. - By fetching the generator first, you bypass the temporary method object issue—you're calling
senddirectly on the live generator instance (if it still exists). - This fits your message protocol scenario perfectly: you can send messages safely without holding a strong reference to the generator, and you get explicit handling for when the generator is cleaned up.
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

