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 3 years ago.
Improve this question
Suppose I have the following:
class Product
def __init__(self, name="Pepsi"):
self.name = name
self.daily_sales = []
And the daily_sales object is something like this:
{
"date": 2019-01-01,
"price": 1.99,
"revenue: 283.01
}
And the daily_sales in the Product class will just have a bunch of those sales_objects. My questions is, when should something like a dictionary be converted into a separated class? When does it make sense to, and when does it not make sense to? For example:
ProductDailySale:
def __init__(self, product_id):
self.product_id;
self.date;
self.price;
self.revenue;
My guidance would be to almost never use dicts as data structures with fixed layout.
Instead, use classes. A convenient way to define simple data classes is dataclasses or, in older versions of Python, attrs.
I've found two major advantages to this over using dicts, especially when used with pytype and static code analysis:
It is possible to annotate fields with type signatures (and get static type checking).
Misspelled field names are caught at build time instead of causing failures (sometimes silent — think dict.get() returning None) at run time.
Related
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 1 year ago.
Improve this question
when you want to use some variable that has the same name as one of the keywords in Python, should I use _keyword or keyword_?
I know we should use underscore to not mess up with it but I am not sure about the position of the underscore. Does the position of underscore matter and mean anything?
For example, I am not sure which one (True_ or _True)?
Or in other cases, when you want to use the name of a built-in function as one of your variables in your projects, what should you do? For example, I work with stock data, I have an open variable within my stock variables. So should I write open_ or _open?
What about when you want to use these kinds of variables/methods in a class? Does it matter now where you use underscores?
As stated in https://pep8.org/#function-and-method-arguments
If a function argument’s name clashes with a reserved keyword, it is generally better to append a single trailing underscore rather than use an abbreviation or spelling corruption. Thus class_ is better than clss. (Perhaps better is to avoid such clashes by using a synonym.)
Note that a prefix underscore e.g. _class usually implies a private class attribute or method, something like:
class MyClass:
def __init__(self):
self._my_private_variable = 1
def _my_private_method(self):
pass
Some further info in https://pep8.org/#descriptive-naming-styles
_single_leading_underscore: weak “internal use” indicator. E.g. from M import * does not import objects whose name starts with an underscore.
single_trailing_underscore_: used by convention to avoid conflicts
with Python keyword
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 2 years ago.
Improve this question
Where are the python operators like +, -, * defined? I am a newbie, so please give a detailed answer to this question.
every Python class has built-in methods (can be recognized by the "__" in the beginning and end of their name) that define their behavior. for example, when using print() on an object, the built-in __str__ function is called, and it is different for every class.
you can override these functions with your own implementations.
here is a class named CarCollection:
class CarCollection():
def __init__(self, car_list):
self.cars_in_collection = car_list
now, say for example you want to add two collections together. using the "+" between two instances of this class will raise TypeError: unsupported operand type(s) for +: 'instance' and 'instance', so in order to add two collections together you need to override the __add__ function:
def __add__(self, other_car_collection):
return self.cars_in_collection + other.cars_in_collection
now when you add two collections together and print the result it will look like this:
first_collection = CarCollection(["subaru", "ferrari"])
second_collection = CarCollection(["fiat", "renault"])
print(second_collection + first_collection)
output: subaru, ferrari, fiat, renault
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 6 years ago.
Improve this question
What is the pythonic way to tell the caller of a function what values a given parameter supports?
He is an example for PyQt (for GUI). Say I have a checkbox,
class checkbox(object):
....
def setCheckState(self, value):
....
Here, setCheckState() should only expect checked or unchecked.
PyQt uses a built-in enumeration (i.e. Qt.Checked or Qt.Unchecked), but this is awful. I am constantly in the documentation looking for the enum for the object I am working with.
Obviously PyQt is written in an unpythonic C++ sytle. How should this or a similar problem be handled in Python? According to PEP 435, enums seem to be a recent addition to the language and for very specific applications, so I would assume there is/was a better way to handle this?
I want to make the code I write easy to use when my functions require specific parameter values--almost like a combobox for functions.
The One Obvious Way is function annotations.
class CheckBox(enum.Enum):
Off = 0
On = 1
def setCheckState(self, value: CheckBox):
...
This says quite clearly that value should be an instance of CheckBox. Having Enum just makes that a bit easier.
Annotations themselves aren't directly supported in 2.7, though. Common workarounds include putting that information in the function doc string (where various tools can find it) or in comments (as we already knew).
If looking for a method for your own code: use an annotating decorator. This has the advantage of continuing to work in 3+:
class annotate(object):
def __init__(self, **kwds):
self.kwds = kwds
def __call__(self, func):
func.__annotations__ = self.kwds
#annotate(value=CheckBox)
def setCheckState(self, value):
...
To be a robust decorator it should check that the contents of kwds matches the function parameter names.
That will do the trick
import collections
def create_enum(container, start_num, *enum_words):
return collections.namedtuple(container, enum_words)(*range(start_num, start_num + len(enum_words)))
Switch = create_enum('enums', 1, 'On', 'Off')
Switch is your enum:
In [20]: Switch.On
Out[20]: 1
In [21]: Switch.Off
Out[21]: 2
OK, I got the error of my ways - I mixed up representation with value.
Nevertheless, if you want to enumerate a larger range - in my fake approach you don't have to add values manually. Of course, if you have sequential numbers.
And I hate extra typing :-)
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 6 years ago.
Improve this question
The refutations in this thread make no sense to me whatsoever. Can someone break it down? Make analogies? Why is this an "abusive hack"?
dict(x, **foo)
...given foo = { 'hello': 'world' }, does the following:
dict(x, hello=world)
This is reasonably straightforward -- however, kwargs behavior is only well-defined for keys which actually could be passed as keyword arguments in (all available versions of) Python. Consider something like:
foo = { ('some', 'tuple'): 'value' }
...in which case you have a key which couldn't actually be passed as a keyword argument; to pass **foo would be to exercise behavior which is not intuitively defined to readers, and which some versions of Python (such as Python 3) will explicitly reject.
By contrast:
x = dict(x) # create a new object
x.update(y)
...is relying only on well-defined behavior, and is portable going forward.
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 years ago.
Improve this question
I'm probably missing something obvious here. With the following code:
class Thing():
def __init__(self, name):
self.name = name
that = Thing()
I get the error 'init needs two arguments'. I thought 'self' was one of the arguments and when I try to instantiate the object by putting the name inside the parentheses I get other errors.
Yes, your __init__ takes two arguments: self, and name. When you call Thing(), self is passed implicitly, but you still need to pass the second one explicitly, like Thing("name"). If you're still getting an error when doing that, that's a different story. You should post that error as well.
(And I doubt the error says "init needs two arguments". It would have been more helpful to include the actual error message...)