1

If I pass the list of cities as a variable, then the task completes as expected.

def count_top_rt(tweet_set):
 for tweet in tweet_set:
 print(tweet)
tweet_set = ["Sydney", "London", "Paris"]
print(tweet_set)

If I mis-type the argument name in the function definition, then the task still complete, because the tweet_set variable is global.

def count_top_rt(mis_typed_arguament):
 for tweet in tweet_set:
 print(tweet)
tweet_set = ["Sydney", "London", "Paris"]
print(tweet_set)

It feels like not passing the argument properly is wrong. I have two questions:

  • In the first version, is the argument passing 'properly'?
  • What are the ways I can make sure to be passing the argument correctly?
Prune
78k14 gold badges63 silver badges83 bronze badges
asked Nov 21, 2016 at 20:41
4
  • 5
    Simply never use the same name for a global variable as you use for a local variable. Then this problem never happens. Commented Nov 21, 2016 at 20:43
  • If you use PyCharm or a similar IDE, it will tell you when you do this automatically. Commented Nov 21, 2016 at 21:09
  • 1
    @kindall The problem in the second function isn't that he used the same name for a global and local, it's that the for loop is not using the local variable that it's supposed to. Commented Nov 21, 2016 at 21:10
  • Why do you care? You don't even call the function. Anyway you'd better not use global variables. Commented Nov 21, 2016 at 21:13

3 Answers 3

3

Is the argument passing 'properly'?

Yes, the argument is passed correctly in the first example: your routine depends only on the input parameter.

What are the ways

In the modular philosophy, you cannot effectively protect against this problem: your function isn't allowed to know about anything external. This is where "pure" modular programming and Python's features are a little bit at odds.

As a programmer, the way to ensure this is to use variable names unlikely to collide. In this case, change the name of tweet_set in the test driver (your main program) to some other name. If this is a standing test case, use a name unlikely to appear in a function, such as TEST_DRIVER_tweet_set.

Programming practices

You can use the search capability in your editor to highlight all occurrences of each name. If you highlight each parameter and variable name in turn and "find all", you can see which ones aren't typed properly.

Advanced technique ... just so you know for "some day" ...

There are Python features that let a function look into the stack, grab the stack frame of the next function (the one that called this one), and check its active variables. If you really, really needed to do so, you could have your function check its own parameter names against variable names in each stack frame, all the way to the main program in the operating system.

There is rarely a case where this is useful.

answered Nov 21, 2016 at 20:54
Sign up to request clarification or add additional context in comments.

Comments

2

There is a simple way of checking that:

>>> def count_top_rt(tweet_set):
... print(id(tweet_set))
... for tweet in tweet_set:
... print(tweet)
>>> tweet_set = ["Sydney", "London", "Paris"]
>>> count_top_rt(tweet_set)
1951490534472
Sydney
London
Paris
>>> id(tweet_set)
1951490534472
>>> tweet_set2 = ["Sydney", "London", "Paris"]
>>> count_top_rt(tweet_set2)
1951490565832
Sydney
London
Paris
>>> id(tweet_set2)
1951490565832

as you can see, when a variable is passed as variable, the local variable becomes a reference to it, no matter what is the name of the global. That is because the interpreter goes to the locals stack first to check for the variable (the reason it is a reference is because of functions' parameters' behavior), only then referring to the globals.

answered Nov 21, 2016 at 20:50

Comments

1

The best way to prevent this is avoiding global variables. Put all your code into functions and classes.

def count_top_rt(tweet_set):
 for tweet in tweet_set:
 print(tweet)
def main():
 tweet_set = ["Sydney", "London", "Paris"]
 count_top_rt(tweet_set)
main()

This will throw a NameError if you misspell the argument name in the definition of count_top_rt.

answered Nov 21, 2016 at 21:15

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.