I'm trying to figure out the proper name for these properties which are written using underscores, so that I can read about them and understand them more. They seem to generally be lower level things, more advanced stuff for really explicit behavior.
What terminology is used for these underscore properties/methods?
"Magic Methods". You can learn more about them here: http://docs.python.org/2/reference/datamodel.html#basic-customization
Important ones are:
__init__(): Constructor for a class
__str__() (or __unicode__(): verbose name of the object used whenever string conversion is needed (e.g. when calling print my_object
I'd say those are the one you'll need in the beginning.
"Magic methods" is a term often used for those that are methods. "Double-underscore" is also sometimes used.
PEP 8 describes them as "magic".
Dunder. e.g. __init__ can be referred to as "dunder init". See this alias.
Related
def __remove_client(self, parameters):
try:
client = self.__client_service.remove_client_by_id(int(parameters[0]))
FunctionsManager.add_undo_operation([self.__client_service, self.__rental_service],
UndoHandler.delete_client_entry, [client[0], client[1]])
FunctionsManager.add_redo_operation(eval('self.__add_new_client(client[0].id,client[0].name)'))
And this gives me : 'UI' object has no attribute '__add_new_client'
What should I do? Or is there another way of adding that function to my repo() stack without calling the function while I am at it?
According to the docs on Private methods:
Notice that code passed to exec() or eval() does not consider the classname of the invoking class to be the current class; this is similar to the effect of the global statement, the effect of which is likewise restricted to code that is byte-compiled together. The same restriction applies to getattr(), setattr() and delattr(), as well as when referencing __dict__ directly.
As for why your eval() is pointless, this:
eval('self.__add_new_client(client[0].id,client[0].name)')
is exacty equivalent to if you just ran the code:
self.__add_new_client(client[0].id,client[0].name)
directly. It seems like maybe you were hoping for some kind of delayed lazy evaluation or something but that's not how it works. Perhaps you wanted to pass a partial evaluation of that method such as:
from functools import partial
FunctionsManager.add_redo_operation(partial(self.__add_new_client, client[0].id, client[0].name))
If this is your own code, you shouldn't actually use the __ methods unless you know exactly what you're doing. There is generally no good reason to use this (Guido has even I think regretted the feature in the past). It's mostly just useful in the special case described in the docs, where you might intend a subclass to override a special method, and you want to keep a "private" copy of that method that cannot be overridden.
Otherwise just use the single _ convention for internal attributes and methods.
PEP 8 states that (emphasis mine):
We don't use the term "private" here, since no attribute is really private in Python (without a generally unnecessary amount of work).
I guess it refers to defining the actual class in some other language and then exposing only the public members to the interpreter. Is there some other way to achieve true privateness in Python?
I'm asking just out of curiosity.
No, nothing is truly private in Python.
If you know the method name, you can get it.
I think you might come up with a clever hack, but it would be just that - a hack. No such functionality exists in the language.
(Note: This is not "private" in the sense of C++/C#/Java type private, but it's close)
For a class, you can prefix a variable with '__'. This will cause Python to name mangle it so you can't accidentally call it from outside the class. For example:
class Test(object):
def __init__(self):
self.__number = 5
a = Test()
print a.__number # name error!
On the other hand, this isn't really private. You can access the number with:
print a.__Test_number
But it will prevent accidental mistakes, which is all private should be used for anyway. If it's prefixed with '__' and someone uses the code, their fault if that code breaks later on (they were warned).
There is no true privateness. The best you could do is obfuscate the variable name and then create getters/setters or properties.
The only way to achieve this that I can think of this is to read/write a file every time you need to have access to that variable.
You could also write a program in another language that will only respond to certain classes. Not sure how to go about doing this, though.
In Python, what is the difference between add and __add__ methods?
A method called add is just that - a method with that name. It has no special meaning whatsoever to the language or the interpreter. The only other thing that could be said about it is that sets have a method with the same name. That's it, nothing special about it.
The method __add__ is called internally by the + operator, so it gets special attention in the language spec and by the interpreter and you override it to define addition for object of a class. You don't call it directly (you can - they're still normal methods, they only get called implicitly in some circumstances and have some extra restrictions - but there's rarely if ever a reason - let alone a good reason). See the docs on "special" methods for details and a complete list of other "special" methods.
If you just went through this doc https://docs.python.org/3/library/operator.html and was curious about the differences between e.g.
operator.add(a, b)
operator.__add__(a, b)
Check the source code https://github.com/python/cpython/blob/3.10/Lib/operator.py :
def add(a, b):
"Same as a + b."
return a + b
...
# All of these "__func__ = func" assignments have to happen after importing
# from _operator to make sure they're set to the right function
...
__add__ = add
So
print(3+3) # call `operator.__add__` which is `operator.add`
import operator
print(operator.add(3, 3)) # call `operator.add` directory
To add to the earlier posts, __*__ are often discouraged as names for identifiers in own-classes unless one is doing some hacking on core-python functionality, like modifying / over-loading standard operators, etc. And also, often such names are linked with magical behavior, so it might be wise to avoid using them in own-namespaces unless the magical nature of a method is implied.
See this post for an elaborate argument
I have a class that wants to be initialized from a few possible inputs. However a combination of no function overloading and my relative inexperience with the language makes me unsure of how to proceed. Any advice?
Check out this question asked earlier.
In short, the recommendation is that you use classmethods or isinstance(), with classmethods being heavily favored.
With Python, you should use duck typing. Wikipedia has a good section on its use in Python at http://en.wikipedia.org/wiki/Duck_typing#In_Python
Contrary to what others have answered, it's not rare to check for types in __init__. For example the array.array class in the Python Standard library accepts an optional initializer argument, which may be a list, string, or iterable. The documentation explicitly states different actions take place based on the type. For another example of the same treatment by argument type see decimal.Decimal. Or see zipfile.Zipfile, which accepts a file argument "where file can be either a path to a file (a string) or a file-like object." (Here we see both explicit type checking (a string) and duck typing (a file-like object) all in one!)
If you find explicit type checking in __init__ is getting messy, try a different approach. Use factory functions instead. For example, let's say you have a triangle module with a Triangle class. There are many ways to construct a triangle. Rather than having __init__ handle all these ways, you could add factory methods to your module:
triangle.from_sas(side1, angle, side2)
triangle.from_asa(angle1, side, angle2)
triangle.from_sss(side1, side2, side3)
triangle.from_aas(angle1, angle2, side)
These factory methods could also be rolled into the Triangle class, using the #classmethod decorator. For an excellent example of this technique see Thomas Wouter's fine answer to stackoverflow question overloading init in python.
No, don't check for types explicitly. Python is a duck typed language. If the wrong type is passed, a TypeError will be raised. That's it. You need not bother about the type, that is the responsibility of the programmer.
I have a programming experience with statically typed languages. Now writing code in Python I feel difficulties with its readability. Lets say I have a class Host:
class Host(object):
def __init__(self, name, network_interface):
self.name = name
self.network_interface = network_interface
I don't understand from this definition, what "network_interface" should be. Is it a string, like "eth0" or is it an instance of a class NetworkInterface? The only way I'm thinking about to solve this is a documenting the code with a "docstring". Something like this:
class Host(object):
''' Attributes:
#name: a string
#network_interface: an instance of class NetworkInterface'''
Or may be there are name conventions for things like that?
Using dynamic languages will teach you something about static languages: all the help you got from the static language that you now miss in the dynamic language, it wasn't all that helpful.
To use your example, in a static language, you'd know that the parameter was a string, and in Python you don't. So in Python you write a docstring. And while you're writing it, you realize you had more to say about it than, "it's a string". You need to say what data is in the string, and what format it should have, and what the default is, and something about error conditions.
And then you realize you should have written all that down for your static language as well. Sure, Java would force you know that it was a string, but there's all these other details that need to be specified, and you have to manually do that work in any language.
The docstring conventions are at PEP 257.
The example there follows this format for specifying arguments, you can add the types if they matter:
def complex(real=0.0, imag=0.0):
"""Form a complex number.
Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
"""
if imag == 0.0 and real == 0.0: return complex_zero
...
There was also a rejected PEP for docstrings for attributes ( rather than constructor arguments ).
The most pythonic solution is to document with examples. If possible, state what operations an object must support to be acceptable, rather than a specific type.
class Host(object):
def __init__(self, name, network_interface)
"""Initialise host with given name and network_interface.
network_interface -- must support the same operations as NetworkInterface
>>> network_interface = NetworkInterface()
>>> host = Host("my_host", network_interface)
"""
...
At this point, hook your source up to doctest to make sure your doc examples continue to work in future.
Personally I found very usefull to use pylint to validate my code.
If you follow pylint suggestion almost automatically your code become more readable,
you will improve your python writing skills, respect naming conventions. You can also define your own naming conventions and so on. It's very useful specially for a python beginner.
I suggest you to use.
Python, though not as overtly typed as C or Java, is still typed and will throw exceptions if you're doing things with types that simply do not play nice together.
To that end, if you're concerned about your code being used correctly, maintained correctly, etc. simply use docstrings, comments, or even more explicit variable names to indicate what the type should be.
Even better yet, include code that will allow it to handle whichever type it may be passed as long as it yields a usable result.
One benefit of static typing is that types are a form of documentation. When programming in Python, you can document more flexibly and fluently. Of course in your example you want to say that network_interface should implement NetworkInterface, but in many cases the type is obvious from the context, variable name, or by convention, and in these cases by omitting the obvious you can produce more readable code. Common is to describe the meaning of a parameter and implicitly giving the type.
For example:
def Bar(foo, count):
"""Bar the foo the given number of times."""
...
This describes the function tersely and precisely. What foo and bar mean will be obvious from context, and that count is a (positive) integer is implicit.
For your example, I'd just mention the type in the document string:
"""Create a named host on the given NetworkInterface."""
This is shorter, more readable, and contains more information than a listing of the types.