Okay, let's try to figure out what exactly the issue is, try to delete local variable topic
after the loop,
def publish(topic, payload):
print(f"Publish -> Topic: {topic}, Payload: {payload}")
publishers = []
for topic in TOPICS:
print(topic)
pub = lambda payload: publish(topic, payload)
publishers.append(pub)
del topic ########## <--------------------------------- This one
pub1, pub2 = publishers
pub1("HI!")
pub2("HI!")
If you do this, Python will throw error later when trying to evaluate pub1
:
Traceback (most recent call last):
File "<input>", line 14, in <module>
File "<input>", line 9, in <lambda>
NameError: name 'topic' is not defined
So, it means that Python is looking for the local variable reference for topic
, and that is why your output has only the second topic always, because by the time loop exits, topic is always going to have the last item in the list.
Further Debugging:
Try chaning your publish
function, and return the id
of the variable topic in the formatted string:
def publish(topic, payload):
print(f"Publish -> Topic: {id(topic)}, Payload: {payload}")
The output will be as follows:
dacha/1
dacha/2
Publish -> Topic: 2574286013360, Payload: HI!
Publish -> Topic: 2574286013360, Payload: HI!
As you can see, both the topic has same id
, it's undoubtedly True that both refer to the same value.
So, how to resolve?
You can, instead of using local variable, use the variable within the scope of lambda
function.
You can change your lambda function to:
lambda payload, topic=topic: publish(topic, payload)
What it will do is, it will keep another variable named topic
with in the scope of lambda
itself, that being said, it will store it's own copy of the value for topic
, and the result remains intact despite the action that changes the value of local variable topic
later.
OUTPUT:
dacha/1
dacha/2
Publish -> Topic: dacha/1, Payload: HI!
Publish -> Topic: dacha/2, Payload: HI!