Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Object-Oriented Python (retired) Objects Create a Class with a Method

Adding a method test?

This does work, just not in this test. Why not?

method.py
class Store:
  open = 9
  close = 9
  def hours(open=open,close=close):
    return "We're open from {} to {}.".format(open,close)

2 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,454 Points

A method needs to have the instance reference as its first argument:

class Store:
    open = 9
    close = 9
    def hours(self, open=open,close=close):
        return "We're open from {} to {}.".format(open,close)

Can the instance reference ever be the (First Position)+1 ... argument? Thanks for all your help today.

Chris Nelson
Chris Nelson
4,603 Points

I don't understand why you need (self, open=open, close=close) as the arguments in the method. Can someone please explain?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,454 Points

For a bound method (meaning the method is defined within the class definition), the first parameter is expected to be a placeholder for the instance of that class for regular methods or a placeholder for the class in a classmethod.

These placeholders are used to hold an pointer to the specific instance (or class) the method belongs to. This is to allow methods a "hook" to use when operating on this instance (or class). The name of the placeholder can be anything, such a "this", "bob", etc. but the standard in Python is to use "self". This placeholder must be the first parameter. This first parameter is assigned this pointer.

Using your original code:

In [22]: class Store:
    open = 9
    close = 10
    def hours(openhours=open, closehours=close):
        return "We're open from {} to {}.".format(openhours, closehours)
   ....:     

In [23]: id(Store)
Out[23]: 140177415253640

In [24]: my_store = Store()

In [25]: my_store
# This is the pointer to the 'my_store' instance
Out[25]: <__main__.Store instance at 0x7f7d990b10e0>

In [26]: id(my_store)
# ID of an object is the decimal representation off the hexadecimal pointer value
Out[26]: 140177415278816

In [27]: my_store.hours()
# The first parameter 'openhours' is assigned the instance pointer
Out[27]: "We're open from <__main__.Store instance at 0x7f7d990b10e0> to 10."

In [28]:  hex(140177415278816)
Out[31]: '0x7f7d990b10e0'

As to Chris' comment, you don't have to define the hours method using the 'open' and 'close' parameters. Two options:

Option 1 using 'open' and 'close' parameters

By using the 'open' and 'close' parameters and assigning them the defaults of the attributes open and close, these values can be used directly in the format statement ....".format(open, close)

Option 2 omitting the 'open' and 'close' parameters

By not using the 'open' and 'close' parameters, these values must be obtained from the instance using the self instance pointer for use in the format statement ....".format(self.open, self.close). This passes the challenge:

class Store:
  open = 9
  close = 9
  def hours(self):
    return "We're open from {} to {}.".format(self.open, self.close)

Both options could be also be done to allow the method to accept an argument that overrides the instance value.

This has to do with reassigning the variables. It is a local vs global scope understanding.

This is what is really going on.

Example:

class Store:
  open = 9
  close = 9
  def hours(openhours=open,closehours=close):
    return "We're open from {} to {}.".format(openhours,closehours)

[MOD: added ```python formatting -cf]

Chris Freeman
Chris Freeman
Treehouse Moderator 68,454 Points

I've updated my previous answer with notes on not using an instance parameter.