This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Real world example about how to use property feature in python?
I have a question about the decorator #property that I've seen in the following code. Could someone be kind enough to completely explain why someone would use the #property decorator? I know #property is equivalent to isActive = property(isActive) but what does the method property actually do to it's parameter? If I were to call the isActive method from the InputCell class what would actually happen? Thanks in advance.
class InputCell(object):
def __init__(self, ix, iy, inputData):
self.ix = ix
self.iy = iy
self.InputData = inputData
#property
def isActive(self):
return self.InputData[self.ix][self.iy]
It's simply syntactic sugar. It allows a method call to look like a variable access or assignment.
One way this can be useful is if you want to change something that previously was a simple variable to something that's actually computed or validated with other code. If you make it a property, you can do this without breaking any existing code. Another way is for caching, lazy initialization, etc., of object attributes.
Related
This question already has answers here:
What is the difference between a function, an unbound method and a bound method?
(6 answers)
Closed 2 years ago.
I am switching from MATLAB to Python and numpy and I would like to know if there is any difference between the option to define a class method and the option to the function to a class field (instance variable)? Here is the example:
class MyClass:
def __init__(self, a):
self.a=a #some variable
def add(self,b):
return self.a+b
vs
class MyClass:
def __init__(self, a):
self.a=a #some variable
self.add = lambda b: self.a+b
It works in both cases when I call
my_object=MyClass(2)
print(my_object.add(2)) #prints 4
Are there any differences between these two approaches? Any best practices/downsides?
To me, the first one feels more "proper OOP", but the second one feels more flexible. Or, maybe, the definitions are identical, because of the way Python works under the hood?
The second one can't be overridden and takes a lot more space, because there's a separate function in every instance's __dict__ instead of one function in the class __dict__. (Instance method objects are created and reclaimed on the fly if you do it the normal way, or optimized out entirely in many cases depending on Python version.)
This question already has answers here:
map doesn't work as expected in python 3
(2 answers)
Closed 2 years ago.
I guess map function is a value-returning function, but how could I use it with a function that return nothing, for example:
class People:
member = ''
def __init__(self, name):
self.member = name
def addPerson(self, member):
self.member += member
b = People("Jack")
map(b.addPerson, ['Michale','Joe'])
And what I want is :
b.member == 'JackMichaleJoe'
Thanks
You don't. The point of map is to perform a conversion of the input (not an in-place mutation). Using map (or comprehensions) for side-effects is bad style and makes for confusing code.
What you do is a normal for loop:
for person in ['Michale','Joe']: b.addPerson(person)
Incidentally, your
member = ''
is at best useless and at worst actively harmful. It defines a class attribute member which is not of any use because it's shadowed by the instance attribute of the same name.
and
def addPerson(self, member):
self.member += member
while this sort of thing can be useful, Python developers generally avoid them unless they're actually useful / necessary. Here, I don't personally feel this method pulls its weight. And the naming is not conventional, it should be add_person.
This question already has answers here:
How do I check (at runtime) if one class is a subclass of another?
(10 answers)
Closed 3 years ago.
At runtime, I want to check whether a specified child class is derived from a specified parent class.
With an object instance, it's easy:
def is_related(child_instance, parent_type):
return isinstance(child_instance, parent_type)
Is there some way to do this without having (or creating) an instance of the child but, instead, having a reference to the child's type?
Something like...
def is_related(child_type, parent_type):
return is_child_class(child_type, parent_type)
Provide an implementation for is_child_class will answer this question.
(By comparison, types in C# know about their supertypes. I don't know whether this is also true in Python.)
Let's say that ChildClass is a subclass of ParentClass. Then
issubclass(ChildClass, ParentClass)
would return True
Here is a possible solution:
class A:
pass
class B(A):
pass
issubclass(B, A) # True
This is what you need to define the is_child_class method as:
def is_child_class(child_type, parent_type):
return issubclass(child_type, parent_type)
This question already has answers here:
Why won't dynamically adding a `__call__` method to an instance work?
(2 answers)
Closed 4 years ago.
I have a wrapper class similar to this (strongly simplified) example:
class wrap(object):
def __init__(self):
self._data = range(10)
def __getitem__(self, key):
return self._data.__getitem__(key)
I can use it like this:
w = wrap()
print w[2] # yields "2"
I thought I could optimize and get rid of one function call by changing to this:
class wrap(object):
def __init__(self):
self._data = range(10)
self.__getitem__ = self._data.__getitem__
However, I receive a
TypeError: 'wrap' object does not support indexing
for the print w[2] line with the latter version.
The direct call to the method, i.e., print w.__getitem__(2), works in both cases...
Why does the assignment version not allow indexing?
EDIT: Regarding the "closed for duplication"
I agree that the linked question has the same answer. It is, however, not at all clear that they are the same question. In particular, someone who does not know the answer here, also does not know that there is an overarching "type of problem" at work. Thus, it won't be clear that they find the answer in a seemingly unrelated question about __call__.
Special methods (essentially anything with two underscores on each end) have to be defined on the class. The internal lookup procedure for special methods completely skips the instance dict. Among other things, this is so if you do
class Foo(object):
def __repr__(self):
return 'Foo()'
the __repr__ method you defined is only used for instances of Foo, and not for repr(Foo).
This question already has answers here:
OOP: getter/setter methods [duplicate]
(2 answers)
Closed 5 years ago.
If I have a python class that looks like this:
class MyClass(object):
def __init__(self, path):
self.path = path
I know I can change the path attribute in an instance of the object like this:
my_example = MyClass("home/data")
my_example.path = "home/other_data"
However, I have seen some code where people use functions to set attributes like this:
class MyClass(object):
def __init__(self, path):
self.path = path
def setPath(self, path):
self.path = path
If I want the user of an instance of the class to be able to change an attribute, it is best practice to have a function for this like in the second example, or to just let them change it manually like the first example?
This depends on the modularity you need in the application. For overall systems design, it's better to make the user access all of the class attributes through class methods. This adds a lot of bloat: get/set methods for each attribute, with further methods for actual manipulation.
In practical terms, you need to decide how much you can trust your user. Python tends to code more directly: let the user make mistakes directly. It's less code for you, and easier for most users.
However, consider the volatility of your design. Do you need to hide the class representation from the user? Do you need to change it once in a while? These are excellent reasons to place the internal representation behind the shield of a simple, unchanging interface: that way, you can change the internals without breaking all of your users' implementations.