Shaokan
Shaokan

Reputation: 7684

python memory question

Say I have a text file of 1 MB. Considering the following the example:

class A:

    def __init__(self, file):
        self.file = file

class B:

    def __init__(self, file):
        self.a = A(file)

f = open(path, 'r')
file = f.read()
f.close()

x = B(file)

Am I creating two files and therefore wasting two megabyte instead of 1? Or python recognizes the file object and just gives a reference to the original file?

Side Question: Is it better to use a global variable in this instance?

Upvotes: 1

Views: 159

Answers (6)

Matt Warren
Matt Warren

Reputation: 696

Just a tip: You should not use file as a name as it is a function within python.

You can do

myfile=open('somepath','r')

and

myfile=file('somepath','r')

open is the preferred way.

in fact, I believe open() uses file() so reassigning file should create some strange behaviour.

Upvotes: 1

Erik Youngren
Erik Youngren

Reputation: 811

Python passes arguments by reference, so essentially the 'string' you pass into B() is actually a pointer (a memory address) to the actual string. If you look at the objects at each point in execution of your example script, you'll see that they are all the same.

For example, this version prints a repr() of the passed object (using object.__repr__ because str.__repr__ prints the data):

class A:
    def __init__(self, f):
        print(repr(self), "received", object.__repr__(f))
        self.f = f


class B:
    def __init__(self, f):
        print(repr(self), "received", object.__repr__(f))
        self.a = A(f)



with open(LARGE_FILE, 'rb') as f:
    text = f.read()

print("passing", object.__repr__(f), "into B()")
x = B(text)

Results in something like this:

passing <str object at 0x280f960> into B()
<__main__.B object at 0x290acd0> received <str object at 0x280f960>
<__main__.A object at 0x290add0> received <str object at 0x280f960>

As you can see, when the string variable is passed into the constructors for A() and B(), it is the same object: actually a pointer to the string.

Very little additional memory is consumed by this.

Upvotes: 4

Matt Joiner
Matt Joiner

Reputation: 118680

Am I creating two files and therefore wasting two megabyte instead of 1?

No. In fact, no file is created in the first place.

Or python recognizes the file object and just gives a reference to the original file?

Only a reference to a wrapper around the OS file handle is passed in the example given.

Side Question: Is it better to use a global variable in this instance?

Definitely not.

Upvotes: 1

glglgl
glglgl

Reputation: 91139

  1. No, Python works with references, so there is only one file data object in your example.

  2. Global variables should be avoided whenever it is possible to do so. Only use them when there is really no alternative.

Upvotes: 1

Fred Foo
Fred Foo

Reputation: 363817

You are reading the file once, so its contents is stored in memory once. What happens is:

  • the file contents are read in and called file;
  • a reference is passed to the B initializer;
  • that passes a reference to the A initializer;
  • that stores the reference;
  • the initializers return references to the objects they created.

It's important to realize that Python always passes arguments and returns values by reference. Variables in Python are just names for objects, not storage locations.

Upvotes: 3

Mariy
Mariy

Reputation: 5924

You are passing just the reference. No wasting of memory.

Upvotes: 1

Related Questions