1

I'm a new programmer and am having issues with passing a new dictionary name as a parameter to a function.
I'm trying to create a function that will pull down data from a webpage and create a dictionary key for the hostname and a value of the full line of data. There are multiple pages that have the commonality of the hostname as a key value, which I will eventually join together in a single row.

First, I create a list called control used as a key file of all the hosts I'm searching for. I then pass the values webpage, delimiter, and dictionary name to the function.
When doing this, it seems the name of the dictionary is not being passed to the function.

#open key file
f = open("./hosts2", "r")
control = []
for line in f:
    line = line.rstrip('\n')
    line = line.lower()
    m = re.match('(^[\w\d]+)', line)
    control.append(m.group())
# Close key file
f.close()

def osinfo(url, delimiter, name=None):
    ufile = urllib2.urlopen(url)
    ufile.readline()
    name = {}
    for lines in ufile.readlines():
        lines = lines.rstrip("\n")
        fields = lines.split(delimiter)
        m = re.match(r'(?i)(^[a-z0-9|\.|-]+)', fields[1].lower())
        hostname = m.group()
        if hostname in control:
            name[hostname] = lines
    print "The length of osdata inside the function:", len(name)

osdata = {}
osinfo(‘http://blahblah.com/test.scsv’, ';', name='osdata')
print "The length of osdata outside the function", len(osdata)

The output is as follows:

$./test.py
The length of osdata inside the function: 11
The length of osdata outside the function: 0

It seems that the keyword is not being picked up by the function.

Is this due to scope?

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
sigsegv
  • 37
  • 3
  • I'm not sure if it is just from copying and pasting your code but your have a large block of code indented further than necessary. After `name = {}` the next 8 lines look like they are indented too far. – Matthew May 16 '13 at 17:52
  • Parameters are not passed to a function. It's objects that are passed as arguments. Parameter are the identifiers defined inside the brackets of a function's definition – eyquem May 16 '13 at 18:03

2 Answers2

3

Instead of passing a string name='osdata' you should pass the object name=osdata.

And don't redefine it again inside the function: name = {}, otherwise you'll lose the reference to the original object.

>>> def func(name=None):
    name ={}         #redefine the variable , now reference to original object is lost
    return id(name)
... 
>> dic={}
>>> id(dic),func(dic)   #different IDs
(165644460, 165645684)

Must read : How do I pass a variable by reference?

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
1

You pass a name argument, and then initialize name with {} inside your function before any use of name: as if no name arg was passed.

def osinfo(url, delimiter, name=None):
    ufile = urllib2.urlopen(url)
    ufile.readline()
    name = {}                               # you define name here as empty dict
        for lines in ufile.readlines():
            lines = lines.rstrip("\n")
            fields = lines.split(delimiter)
            m = re.match(r'(?i)(^[a-z0-9|\.|-]+)', fields[1].lower())
            hostname = m.group()
            if hostname in control:
                name[hostname] = lines
        print "The length of osdata inside the function:", len(name)

Two comments then

  • if you want to modify the dictionary, pass it as an argument, not its name

  • you are right for one point: in Python, if object passed as an argument is mutable, variable living in the outside scope and passed as an argument can be modified by the function (as if it where passed by reference, althought it is more precisely that a reference to the object is passed by value, see here)

Community
  • 1
  • 1
kiriloff
  • 25,609
  • 37
  • 148
  • 229