Setting up instance variables Python - python

I know that there are tons of questions asking this but no methods I have found anwer exactly what I want. When ever I run this code and subsiquently getIngredient() I get this error 'ListItem' object has no attribute 'ing'. Please help and thanks in advance.
class ListItem(FloatLayout):
def __init__(self, ing):
super(ListItem, self).__init__()
self.ing = ing
def getIngredient(self):
return self.ing.name
I am also calling this on an instance of the object put into a box layout in kivy.

Well, if I paste that code into a Python 2.7.10 iPython session, using a stub/empty FloatLayout class, then the error I get from instantiating with just a string, and calling the getIngredient() method, is:
AttributeError: 'str' object has no attribute 'name'
... which seems perfectly expectable. If I create some object and give it a .name attribute then the code works fine.
So it seems likely that your problem either involves some details of the real FloatLayout parent class; or the version of Python that you're using (or both).
In general I'd expect that you'd add your own custom attributes (.ing in your example) before your call to super() ... if you're adding stuff rather than over-riding it. (In general I'd also expect you to pass any initialization arguments up the chain to your super-classes (after filtering out any that you're intercepting as specific to your derived/child class). Done properly that should make you relatively robust even if the implementation of your parent class changes somewhat and even if descendants of your class attempt to utilize as yet un-imagined extensions of your parent classes.
(I know, that sort of "future proofing" is vague, and abstract, and even somewhat fragile ... but it's better than ignoring the issue entirely).

Related

When is it acceptable to declare an instance attribute outside "__init__()"?

I will start by describing the dilemma I'm currently facing. I've a class (let's call it NeatClass). It has several instance attributes, all of which I declare, as usual, within the class' __init__() method. I'm adding a new method (let's call it util_method()) to the class and it requires an internal state to be kept between calls. My intention is to store that state in an instance attribute (let's call it self._util_attr).
Now, according to the "usual guidelines", I should declare self._util_attr inside NeatClass.__init__():
class NeatClass:
def __init__():
self.attr1 = ...
self.attr2 = ...
# ...
self._util_attr = None # type: ignore
I understand that declaring instance attributes inside __init__() is supposed to increase the code's readability (see this and this SO questions) - I totally agree with it. However, in my use-case, doing so might have the opposite effect. Here's why:
In my class, only util_method() is supposed to use self._util_attr.
Although I want util_method to be part of my class' API, it will only be used in some rare occasions (most instances of NeatClass won't use this method at all).
I'm using mypy to type-hint my code. During the call to NeatClass.__init__(), the type of self._util_attr isn't known (hence the comment # type: ignore). For reasons that are outside the scope of this question, I can't use Union or something like that to type-hint this variable.
So, what I really want to be doing is this:
class NeatClass:
def __init__():
self.attr1 = ...
self.attr2 = ...
# ...
def util_method(self):
if not hasattr(self, "_util_attr"):
self._util_attr = ... # initial value of the variable
# ...
However, I want my code to follow both PEP8 and Google Python Style Guide. So, I searched both guidelines for references to situations in which declaring an instance attribute outside __init__() is acceptable. As you might have imagined, I didn't find anything. As a matter of fact, I didn't find anything about "declaring instance attributes inside __init__()" at all, which really came as a surprise. This lead us to my question:
Are there any situations in Python's common style guidelines (especially PEP8 and Google's) in which it is acceptable to declare instance attributes outside __init__()__?
Pointers to where, in those guidelines, it's specified that instance attributes should only be declared inside __init__() would also be appreciated. Also, suggestions on how to refactor my code are welcome.
Please note that I'm not looking for opinions (which, in turn, would violate StackOverflow's guideline). I'm simply looking for references to sections of Python's most common style guidelines that address the situation I described. I also don't think this question is a duplicate - I've read several other SO's questions on the subject and none of them seemed to be asking the same thing I'm asking here.
Thank you for your time!

How to check if method exist from within a Python object

Context and intentions: I want to use an object m_o of type My_object as a way of interfacing with another object called s_o of type Stubborn_object. For the sake of easy understanding, they should behave like if My_object inherited from Stubborn_object, in the way that calling an attribute that doesn't exist in My_object should call the attribute in Stubborn_object.
However, the tricky thing is that I wouldn't be asking this question if I could simply inherit My_object from Stubborn_object. It appears that I can't inherit from it, and, for many reasons, I also can't modify the code of the Stubborn_object class, so I have to use it as it is. Please note that trying to inherit isn't the issue of the question here. I know that other solutions exist for my practical problem, but I really want answers to stay on topic for many reasons. I suspect that other users can have different problems than mine and still be unable to inherit a class. Furthermore, not being able to inherit a class is not the only reason that could make someone read this question. In fact, it's quite a general Python object-oriented problem. I also believe the solution of my problem could be useful in other applications, like custom error handling within the object itself when an attribute is not found, or in thread management to lock the instance as soon as an attribute is called.
In addition to the problem of inheritance, let's suppose that I can't use conditions at higher levels to handle these cases, so everything has to be done inside My_object instance or its parents. That means that I can't use hasattr(m_o, attribute_name) to determine if I should call getattr(m_o, attribute_name) or getattr(s_o, attribute_name). This also means that any try/except blocks and other preconditions must be inside the My_object class or its parents. The point of this question is not about detecting exceptions when calling an attribute from outside the My_object instance. A try/catch block normally has to be outside the My_object class, and I previously stated that this can't be allowed.
For the sake of clarity and to provide a complete verifiable example, here is a sample code of the Stubborn_object class. I know that I said I can't inherit from Stubborn_object and the following code includes an inheritable class. Providing an example of an non-inheritable object would only bring confusion and it would'nt be really helpful to the question anyway, so here is a simple example of an inheritable object. The objective of this is to make an easy to understand question, so please just consider that you can't inherit from it:
class Stubborn_object:
def do_something(self):
print("do_something")
def action_to_override():
print("action_to_override")
def action_a(self):
print("action_a")
def action_b(self):
print("action_b")
Objective: Put it simply, I want my class My_object to detect all by itself that a lacking attribute has been called and run some instructions instead of throwing an AttributeError.
Current attempts: Right now, I manually redirect method calls to the Stubborn_object instance like so (it's successful, but not reliable nor scalable because of the use of hardcoding):
class My_object():
def __init__(self, s_o):
self.stubborn_object = s_o
def action_to_override(self):
# Do stuff. This method "overrides" the Stubborn_object.action_to_override method.
print("Here is stuff getting done instead of action_to_override")
def action_a(self):
return self.stubborn_object.action_a()
def action_b(self):
return self.stubborn_object.action_b()
s_o = Stubborn_object()
m_o = My_object(s_o)
m_o.action_to_override() # Executes Stubborn_object.do_something()
m_o.action_a() # Executes Stubborn_object.action_a()
m_o.action_b() # Executes Stubborn_object.action_b()
Executing this code along with the provided Stubborn_object code sample should print:
Here is stuff getting done instead of action_to_override
action_a
action_b
As you can see from methods action_a and action_b, I have to manually call the Stubborn_object methods from whithin the methods in My_object to mimic the attributes of Stubborn_object. This is ineficient, lacks of robustness and will throw an AttributeError exception if we attempt to make an action that wasn't included in the My_object code.
What if I wanted to automatically send method and attribute calls to the Stubborn_object instance without having to rewrite all of its method and attributes in My_object? I believe this can be achieved with detecting if a lacking attribute of My_object instance is called.
Expectations (or sort of): I am open to any solution that allows the My_object class or its parents to determine if the attribute is lacking or not, all within itself. So I believe I am ready to hear extremely original ideas, so go ahead.
On my part, I believe that something that uses parts of this code is the way to go, but it still lacks the "catch any called attribute" part:
class My_object():
def __init__(self, s_o):
# __init__ stays as it was.
self.stubborn_object = s_o
def action_to_override(self):
# This method also stays as it was.
# Do stuff. This method "overrides" the stubborn_object.action_to_override method.
print("Here is stuff getting done instead of action_to_override")
def run_me_when_method_is_not_found(self, method_name, **kwargs):
print("Method " + method_name + " not in 'My_object' class.")
return getattr(self.stubborn_object, method_name)(**kwargs)
So running those lines with the previous code sample
s_o = Stubborn_object()
m_o = My_object(s_o)
m_o.action_to_override() # Executes Stubborn_object.do_something()
m_o.action_a() # Executes Stubborn_object.action_a()
m_o.action_b() # Executes Stubborn_object.action_b()
will print
Here is stuff getting done instead of action_to_override
Method action_a not in 'My_object' class.
action_a
Method action_b not in 'My_object' class.
action_b
Some similar methods will have to be made for getters and setters, however, the idea stays the same. The thing is that this code lacks the ability to detect that an attribute is missing.
Question: How can I run the run_me_when_method_is_not_found when the method is not found in My_object? Especially, how can a My_object instance detect that the method doesn't exists in its class instead of throwing an AttributeError exception?
Thanks a lot.
Seems like overriding __getattribute__ will do exactly what you want: search for attribute in self.stubborn_object if it is missing in self. Put it into My_object class definition:
def __getattribute__(self, attr):
try:
return object.__getattribute__(self, attr)
except AttributeError:
return object.__getattribute__(self.stubborn_object, attr)

Defining a class property within __init__ as opposed to within another class method -- python

EDIT
Note, it was brought to my attention that Instance attribute attribute_name defined outside __init__ is a possible duplicate, which I mostly agree with (I didn't come upon this because I didn't know to search for pylint). However, I would like to keep this question open because of the fact that I want to be able to reinitialize my class using the same method. The general consensus in the previous question was to return each parameter from the loadData script and then parse it into the self object. This is fine, however, I would still have to do that again within another method to be able to reinitialize my instance of class, which still seems like extra work for only a little bit more readability. Perhaps the issue is my example. In real life there are about 30 parameters that are read in by the loadData routine, which is why I am hesitant to have to parse them in two different locations.
If the general consensus here is that returning the parameters are the way to go then we can go ahead and close this question as a duplicate; however, in the mean time I would like to wait to see if anyone else has any ideas/a good explanation for why.
Original
This is something of a "best practices" question. I have been learning python recently (partially to learn something new and partially to move away from MATLAB). While working in python I created a class that was structured as follows:
class exampleClass:
"""
This is an example class to demonstrate my question to stack exchange
"""
def __init__( self, fileName ):
exampleClass.loadData( self, fileName )
def loadData( self, fileName ):
"""
This function reads the data specified in the fileName into the
current instance of exampleClass.
:param fileName: The file that the data is to be loaded from
"""
with open(fileName,'r') as sumFile:
self.name = sumFile.readLine().strip(' \n\r\t')
Now this makes sense to me. I have an init class that populated the current instance of the class by calling to a population function. I also have the population function which would allow me to reinitialize a given instance of this class if for some reason I need to (for instance if the class takes up a lot of memory and instead of creating separate instances of the class I just want to have one instance that I overwrite.
However, when I put this code into my IDE (pycharm) it throws a warning that an instance attribute was defined outside of __init__. Now obviously this doesn't affect the operation of the code, everything works fine, but I am wondering if there is any reason to pay attention to the warning in this case. I could do something where I initialize all the properties to some default value in the init method before calling the loadData method but this just seems like unnecessary work to me and like it would slow down the execution (albeit only a very small amount). I could also have essentially two copies of the loadData method, one in the __init__ method and one as an actual method but again this just seems like unnecessary extra work.
Overall my question is what would the best practice be in this situation be. Is there any reason that I should restructure the code in one of the ways I mentioned in the previous paragraph or is this just an instance of an IDE with too broad of a code-inspection warning. I can obviously see some instances where this warning is something to consider but using my current experience it doesn't look like a problem in this case.
I think it's a best practice to define all of your attributes up front, even if you're going to redefine them later. When I read your code, I want to be able to see your data structures. If there's some attribute hidden in a method that only becomes defined under certain circumstances, it makes it harder to understand the code.
If it is inconvenient or impossible to give an attribute it's final value, I recommend at least initializing it to None. This signals to the reader that the object includes that attribute, even if it gets redefined later.
class exampleClass:
"""
This is an example class to demonstrate my question to stack exchange
"""
def __init__( self, fileName ):
# Note: this will be modified when a file is loaded
self.name = None
exampleClass.loadData( self, fileName )
Another choice would be for loadData to return the value rather than setting it, so your init might look like:
def __init__(self, fileName):
self.name = self.loadData(fileName)
I tend to think this second method is better, but either method is fine. The point is, make your classes and objects as easy to understand as possible.

Re-initializing parent of a class

I have become stuck on a problem with a class that I am writing where I need to be able to reinitialize the parents of that class after having created an instance of the class. The problem is that the parent class has a read and a write mode that is determined by passing a string to the init function. I want to be able to switch between these modes without destroying the object and re-initialising. Here is an example of my problem:
from parent import Parent
class Child(Parent):
def __init__(mode="w"):
super.__init__(mode=mode)
def switch_mode():
# need to change the mode called in the super function here somehow
The idea is to extend a class that I have imported from a module to offer extended functionality. The problem is I still need to be able to access the original class methods from the new extended object. This has all worked smoothly so far with me simply adding and overwriting methods as needed. As far as I can see the alternative is to use composition rather than inheritance so that the object I want to extend is created as a member of the new class. The problem with this is this requires me to make methods for accessing each of the object's methods
ie. lots of this sort of thing:
def read_frames(self):
return self.memberObject.read_frames()
def seek(self):
return self.memberObject.seek()
which doesn't seem all that fantastic and comes with the problem that if any new methods are added to the base class in the future I have to create new methods manually in order to access them, but is perhaps the only option?
Thanks in advance for any help!
This should work. super is a function.
super(Child, self).__init__(mode=mode)

Why do base classes in Python need to extend object?

I'm looking for a clear explanation of why my base classes must extend object if I want to use super
# Without extending object, this code will fail with
# TypeError: must be type, not classobj
class A(object):
def __init__(self):
print "Called A.__init__"
class AChild(A):
def __init__(self):
super(AChild, self).__init__()
print "Called AChild.__init__"
AChild()
This works as expected, but if you remove object it throws the exception mentioned. I'm using Python 2.7.8. Feel free to link me to any related questions, but I didn't find a good answer with a quick search
It's because by extending object you are using new style classes which are required to support the use of super, which was added alongside the introduction of new style classes to Python.
According to the information in this answer, old style classes had a simple depth-first method resolution order so there was no need for this function, and thats probably why it wasn
t included then. However upon adding multiple inheritance, super is now the recommended way to call a superclass because of the more complicated MRO.

Categories

Resources