Resources on Professional Python Programming [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm looking for a resource that will help me turn my python function definitions into professional quality functions.
For example, my current python definitions have the following form:
def foo(arg1,arg2,arg3=some_val,arg4=some_other_val):
""" Do something with the args """
# Create data using args
if arg3 == this_val:
return dataset_1, dataset_2
else :
return dataset_1, dataset_2, dataset_3
I would like for a way to return the data I'm interested in based on what return data I ask for.
For example, I could say:
ds_1, ds_2, ds_3 = foo(arg1,arg2)
or
ds_1, ds_2 = foo(arg1,arg2,arg3=only_two_datasets_bool)
How do I make it so the function doesn't need the optional argument to know I only want two datasets?
This is analogous to say matplotlib constructors where one can say:
n = plt.hist(data)
where n is the histogram but one can also do
n, bins = plt.hist(data)
and the hist function knows to return those two values with the same input of data (ie no optional arguments stating it should return bins).

While it may seem clunky and inelegant, you could unpack three variables and only use two of them if desired:
def foo(arg1, arg2):
return (arg1,arg2,3)
a, b, _ = asd(1,2)
print a, b # will print "1 2"
While the _ does not mean "unused variable" in python as it does in many other languages, many (or perhaps most) will recognize it as such. Even languages who don't offer explicit support for it, like Lua, encourage the use of _ as a placeholder variable due to conventions.
Use it in such a way that it is clear what the _ means though, as it in python shell contains the value of the previously evaluated expression:
>>> 1+2
3
>>> _+3
6
>>>

Related

Return Order of Magic Methods [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
Improve this question
I've been programming for a couple of months now and now I actually have a question... So, if I am not completely wrong, there is just one return per call, right? Doesn't matter if its None or a certain return but there cant be like 2 return statements in one call? So lets move on to the magic methods. In which order do they get processed?
def __str__(self):
return f"{self.first} {self.second}"
def __repr__(self):
return "{} {}".format(self.first, self.second)
Always the last one? Or are there differences between certain magic methods in terms of ranking systems? Or do they even get both processed but just one becomes returned=?
There is no return order. Each magic method is a hook called by the Python implementation in order to implement specific protocols.
x.__str__ defines what str(x) means.
x.__repr__ defines what repr(x) means.
And that's it. Well, almost.
You also need to know when str or repr might be used aside from explicit calls. Some examples:
print calls str on each of its arguments to ensure that it has str values to write to the appropriate file.
The interactive interpreter calls repr on the value of each expression it evaluates.
In addition, object.__str__ falls back to use __repr__, I think by invoking x.__repr__() directly (rather than calling repr(x), which would then call x.__repr__()). So str(x) can indirectly be implemented using a __repr__ method if no class involved defined a __str__ method.
Other groups of magic methods might cooperate in order to define a more complicated protocol. For example,
x += y
could involve several options, tried in order:
x = x.__iadd__(y), if x.__iadd__ is defined
x = x.__add__(y), if x.__add__ is defined
x = y.__radd__(x), if x.__add__ is not defined or x.__add__(y) returned NonImplemented.

Can I store keywords as values to variables? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
given a string "A & B & C" with values of A,B abd C = 0,0,1 respectively, it would be solved as 0 & 0 & 1 to give a result of 0.
I am writing a program where I want to check for & and | for logic operation to return the result.
in this case, I wish to have something like this logic = and. But unfortunately and is a python reserved keyword and it will throw the error below;
File "<ipython-input-248-9d5aa5c6e082>", line 1
logic = and
^
SyntaxError: invalid syntax
How do I fix this?
You can't use a keyword in this way. You might think that you could use the built-in module operator to achieve your goal. This module contains functions that have the same behaviour as the built-in operators, and you can store a reference to one of those functions.
However, logical and and or are missing from this module (and_ and or_ are bitwise). This is probably because these operators exhibit "short-circuit" behaviour, which can't be emulated in a function call.
If it's okay for you not to have short-circuiting, it's trivial to implement these functions yourself:
>>> and_ = lambda a, b: a and b
>>> logic = and_
>>> logic(True, False)
False
>>> logic(True, True)
True
The difference between functions and operators in python is that functions are objects and operators are not. What this means is that and is not a "thing" in python that you can pass around the way you could pass around a value or a function or an object or a class.
You could pass around "the idea of and", by encapsulating it in a function:
and_logic = lambda x, y: a and b
This means that you'd now have a function which, for any a and b returns the logical result of a and b. This function could now be passed around in potentially useful or interesting ways.
But since you don't give a lot of information about what you want to do in your question, it's hard to be more specific about what you can do with this idea.
EDIT: Just after I submitted this, I learned something from #Thomas' post. Apparently, the work of creating the lambda has been done for you!
Yes, of course. You can do almost fancy things by using Python.
>>> import operator
>>> op = operator.or_
>>> print(op(1, 2))
3

Bind the output of a method before using or call the method when you need its output? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
In both examples, class.method() returns a list.
Example A:
if class.method():
for i in class.method():
# do stuff
Example B
list = class.method()
if list:
for i in list:
# do stuff
Which is better? It would seem to me that in some languages (but I don't know which), example A would result in class.method() being needlessly evaluated twice, and example B would be best practice. However, perhaps other languages (again not knowing which) might retain the output of a method in memory in case that method is called again, therefore avoiding having to do the same evaluation twice and resulting in little difference between examples A and B. Is this so? If so, can you give examples of a language for each case? And the real reason for the question: which is best practice in Python?
Unless your Python interpreter has JIT capabilities, the method will be evaluated every time you call it.
And even when the JIT compilation is possible, methods have to be proven by the compiler / interpreter that they do not have any side effects, that is they are deterministic.
For example, consider a method that pulls data from a database or a method that contains a call to a random number generator:
import random
def method():
return random.uniform(0.0, 1.0)
Output of such a method cannot be saved in memory because the second time you call it, it may change.
On the other hand, getter methods that accumulate data are a great example of a deterministic method, given that they do not call a non-deterministic method in their body.
from dataclasses import dataclass
#dataclass
class Example:
a : list
b : list
def method(self):
return self.a + self.b
In practice, you are better of to not assume anything from the compiler / interpreter and do these small, easy to do optimizations yourself. You also have to consider that your code can be run on multiple platforms, which further complicates things.
So I would recommend you to call the method only once and save its output in a temporary variable:
result = class.method()
if result :
for i in result:
# do stuff
And given that it's Python, I recommend to ask for forgiveness with the try keyword if most of the time you run the method, its output is not None:
result = class.method()
try:
for i in result:
# do stuff
except TypeError:
pass

What's the correct way to pass by reference [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have seen other people ask a question but the only answers I have seen simply explain that python doesn't have the same concept of pass by reference vs pass by value as languages like C do.
for example
x=[0]
def foo(x):
x[0] += 1
In the past, I have been using this work around but it seems very un-pythonic so I'm wondering if there is a better way to do this.
let's assume for what ever reason returning values won't work, like in the case where this code runs on a separate thread.
Some python objects are immutable (tuple, int, float, str, etc). As you have noted, you cannot modify these in-place.
The best workaround is to not try to fake passing by reference, instead you should assign the result. This is both easier to read and less error prone.
In your case, you could call:
x = 0
def f(x):
return x + 1
x = f(x)
If you truly need to fake passing by reference (and I don't see why you would need that), your solution works just fine, but keep in mind that you do not actually modify the object.
x = 0
x_list = [x]
print(id(x_list[0])) # 1844716176
def f(x_list):
x_list[0] += 1
f(x_list)
print(x) # 0, not modified
print(id(x_list[0])) # 1844716208

Initialise several variables at once to the same object but different instances [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
What is the cleanest way of initialising several objects the same way, without making them all point to the same object? I want to do this:
a, b, c = create_object(), create_object(), create_object()
In a less verbose way.
I can do the following, but then all my variables point to the same object
a = b = c = create_object() # then a.change() changes them all!
Is there a clean, pythonic way to do this that I'm missing?
The most pythonic code is the code that makes the most sense. It's a lot better to just do
a = create_object()
b = create_object()
c = create_object()
as opposed to the alternative, a confusing mess of gibberish. Don't be afraid of having two extra lines; really, the benefit is much greater. :-)
Use a factory.
def factory(num):
for i in range(num):
yield shell()
class shell():
pass
a, b, c = factory(3)
# results:
>>> a
<__main__.shell instance at 0x0000000002BE0548>
>>> b
<__main__.shell instance at 0x0000000002BE03C8>
>>> c
<__main__.shell instance at 0x0000000002BE0588>
You can of course, always add extra parameters to be able to initialize a group of variables to be the same, or you could even have complex factories that determine their own parameters to pass to the class constructor.
You could also have it a static method of the class.
Whatever your preference is, if you want to initialize a group of variables to all be difference instances of the same class, this would be how you should do it. (although, in general, that kind of activity is not very pythonic for what it's worth...)
To make a factory using what you have shown, and to make it more robust, here is a nice sample:
def factory(obj, num, args=None):
for i in range(num):
yield obj(args) if args else obj()
a, b, c = factory(create_object, 3)

Categories

Resources