0

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.

  • I removed the FloatLayout related code and run this, I did not encounter any problem. Can you append more of your code(complete picture)? – Junchao Gu Dec 28 '15 at 02:03
  • move the `self.ing=ing` before the super – karthikr Dec 28 '15 at 02:07
  • Are you calling `getIngredientName` on a class instance or the class object? Put any details in the question. – Peter Wood Dec 28 '15 at 02:16
  • Note: you claim to call `getIngredientName`, but the method you defined is named `getIngredient`. That said, if `a` is an object with a `.name` attribute, the following works for me: `ListItem(a).getIngredient()` – Alec Dec 28 '15 at 02:27

1 Answers1

2

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).

Jim Dennis
  • 17,054
  • 13
  • 68
  • 116
  • How do I set it up as an attribute is what in asking – JavaNoob101 Dec 28 '15 at 13:17
  • The term "attribute" can be a bit vague with regards to Python. It's been used to refer generically any data associated with an object/instance (where it classically exists and entries in the __dict__ associated with a normal object). These are also called "members" -- and "methods" (functions bound to a class or instance, and taking references to "self" as their first, implicitly provided, argument are also members or "attributes" of an object. That's because functions are first class objects ... values ... in Python. – Jim Dennis Dec 28 '15 at 14:45
  • Another use of the term "attribute" in reference to Python is more formally referred to as a "descriptor" ... you can read about those here: https://docs.python.org/2/reference/datamodel.html#descriptors – Jim Dennis Dec 28 '15 at 14:46
  • Finally you should be aware that there are special methods, (dunder)getattr()(dunder) and setattr() and the {get,set}attribute which allow one to customize how Python implements the semantics surrounding attribute access (through an object's "." operations ... object.attribute). This allows one to create classes with dynamic/virtual attributes: http://stackoverflow.com/a/3278104/149076 – Jim Dennis Dec 28 '15 at 14:50