0

I have a relatively straightforward question but couldn't really find the answer online. I know in C++, if you are trying to create a large object (say a huge vector of strings) you would avoid doing:

int main() {
    vector<string> v = foo()
}

vector<string> foo() {
    vector<string> result;
    // populate result
    return result;
}

instead opting for the version below because a method call like above will have to copy the local vector to the vector declared in main whereas the lower example adds directly to the vector in main (more or less):

int main() {
    vector<string> v;
    foo(v)
}

void foo(vector<string>& result) {
    // populate result
    return result;
}

My question is the same related to python. Is it better to pass in a mutable object as a parameter or have the method create one locally and return it? I'm not incredibly familiar with the mechanics of Python.

gowrath
  • 3,136
  • 2
  • 17
  • 32
  • 2
    Actually in your C++ example the copy would be elided due to [return value optimization](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization), so I personally prefer the first method for readability and conciseness. – Cory Kramer Aug 02 '16 at 12:55
  • I thought that was a compiler specific trick? Guess I should read up on it :P – gowrath Aug 02 '16 at 12:59
  • 3
    No, you do not need to worry about this in Python. It will not create unnecessary copies of values just because you return them from a function. This is true for most high level languages which do not offer direct manipulation of memory. – deceze Aug 02 '16 at 12:59
  • 1
    My C++ is rusty; a typical Python function is more like (I think) a C++ function that returns a reference to a value rather than the value itself. `vector& foo()`? (Although with the return value allocated on the heap instead of the stack, IIRC.) – chepner Aug 02 '16 at 13:09
  • @Gowrath Newer standards require it in certain situations (well you get move semantics, which is pretty much the same here). But honestly if you're worried about performance and use a c++ compiler who doesn't generate approximately equal code between the first and the second method you're doing something horribly wrong. – Voo Aug 02 '16 at 13:26

1 Answers1

1

Python's data model is very different from C++'s.

In Python, new objects are created on the heap and bound to variables that exist in namespaces (function calls, classes, instances and varaious other parts of the language implement namespaces).

In C++, without proper care you can create an object in a function or method call that is allocated on the stack. Then if your function returns a reference to this object you will see problems, because the memory will likely be re-used, and the reference will become invalid at best and dangerous at worst!

In Python it isn't possible to create a "dangling reference" of this type, because objects are kept alive as long as there are any references to them. Therefore it's perfectly permissible to create new objects inside a function and return them without worries. This will normally be preferable to forcing the caller to create a mutable object for the function to modify.

Anthon
  • 69,918
  • 32
  • 186
  • 246
holdenweb
  • 33,305
  • 7
  • 57
  • 77