3

I was watching Learn Python - Full Course for Beginners [Tutorial] on YouTube here.

At timestamp 4:11:54 the tutor explains what a class function is, however from my background in object oriented programming using other languages I thought the correct term would be method?

Now I am curious if there is a difference between a class function and method?

3
  • 2
    I think you're attributing too much significance to a casual word choice at the end of a very long video. Commented Jan 28, 2023 at 3:01
  • @JohnGordon #autismForLife :-p Commented Jan 29, 2023 at 22:32
  • In simple words there is no difference between a class function and method. Commented Jun 18 at 23:43

3 Answers 3

5

They are wrong. But, it's a minor confusion they made and doing video courses which involves speaking and typing can be certainly challenging. No big deal.

When the function belongs to a class, it's a method (a more specialized form of a function). When it's outside of a class it's a function.

How do I know they are wrong?

You use this syntax to create one in Python:

class SomeClass:

   @classmethod
   def the_method(cls, vars):
       ....

   def instance_method(self, vars):
       ...

It's not a @classfunction decorator. It's a @classmethod decorator.

See the docs at https://docs.python.org/3/library/functions.html#classmethod

Sign up to request clarification or add additional context in comments.

Comments

2

Method is the correct term for a function in a class. Methods and functions are pretty similar to each other. The only difference is that a method is called with an object and has the possibility to modify data of an object. Functions can modify and return data but they dont have an impact on objects.

Edit : Class function and method both mean the same thing although saying class function is not the right way to say it.

2 Comments

I know, but I asked is there a difference between: Class Function and Method?
No class function and method both mean the same thing.
1

You dont need to create an instance with a classmethod. Formatter.format(“foo”) vs Formatter().format(“foo”).

That also means you cant store state/configuration on the instance because there is no instance. Also inheritance and polymorphism may not work as well with classmethods - i.e. if I was planning to bring them into play on a classmethod I’d be very cautious about actual behavior.

In practice you usually want to use regular methods, except on class methods that create instances (which are often called factory methods). If you really don't need an instance, maybe a standalone function would do the job just as well? Python does not require functions to live only on classes (like Java).

As far as terminology goes, don’t sweat it besides exam considerations. Method vs function are not that different except that one has an instance (or the class in a @classmethod) as first argument.

Typically, if it's indented under a class XXX: declaration, I'd call a method. If it was standalone, I'd call it a function.

OK, read further only if you don't mind getting confused a bit...


Besides the distinction between all these things is rather fluid in practice. classmethods can be called from instances, functions can be dynamically added to classes...

Here's some amusing stuff. Most of it is curiosity, except for the create_me classmethod which is the main reason to use classmethods as factories, but it shows the boundaries are fluid-ish.

This is not stuff you'd typically want to do, but it does walk through some of the finer distinctions on how methods/functions on classes can behave.


class Anc:
    @classmethod
    def format(cls, msg):
        "I dont need an instance to work"
        print(f"\n{cls}.format({msg.upper()})") 
        
    def __init__(self, keep=1) -> None:
        self.keep = keep

    def format_instance(self, msg):
        "I do and it allows me to use configuration stored in it"
        print(f"\n{self}.format_instance({msg[:self.keep]=})")

    @classmethod
    def create_me(cls, *args, **kwargs):
        """ a factory is the main reason for class methods """
        return cls(*args, **kwargs)

class Child1(Anc):
    @classmethod
    def format(cls, msg):
        print(f"\n{cls}.format({msg.lower()})") 

    @staticmethod
    def format_static(msg):
        print(f"\nLonely static without cls or instance 😭{msg}😭")

class Child2(Anc):
    def format_instance(self, msg):
        "replace with stars"
        print(f"\n{self}.format_instance({'*' * len(msg)})")


def wannabe_method(self, msg):
    "is this a function or a method?"
    print(f"\nwannabe_method({self},{msg=}).")

def wont_work_as_method():
    "too many arguments when called as method"
    print(f"\nwont_work_as_method()")


Anc.format("calling format as a classmethod.  No instance needed!")

anc = Anc(keep=2)

anc.format("calling format through an instance.  It'll automatically get the class as first argument!")

Child1.format("calling Child1's format, which does lower")

Child2.format("calling Child2's format, which will up on Anc.format")

Child1.format_static("this is a static")

child1 = Child1(keep=3)

child1.format_instance("this message will get truncated...")


child2 = Child2()


try:
    child2.added_method("hey just got added!")
except (AttributeError,) as e: 
    print(f"\n❌as expected this fails {e} cuz missing method")

Child2.added_method = wannabe_method


child2.added_method("hey just got added! self gets the instance magically")


try:
    wannabe_method("nope not gonna work")
except (TypeError,) as e: 
    print(f"\n❌as expected this fails {e} because it only got 1 argument")

wannabe_method("FAKE INSTANCE!", "hackish work")



Child2.wont_work = wont_work_as_method

try:
    child2.wont_work()
except (TypeError,) as e: 
    print(f"\n❌ oh no! no place for self {e}")

child2_through_factory = Child2.create_me()

child2_through_factory.format_instance("My God, it's full of stars")
child2_through_factory.format("to uppercase")

child1_through_factory = Child1.create_me()
child1_through_factory.format("TO LOWERCASE")

output:


<class '__main__.Anc'>.format(CALLING FORMAT AS A CLASSMETHOD.  NO INSTANCE NEEDED!)

<class '__main__.Anc'>.format(CALLING FORMAT THROUGH AN INSTANCE.  IT'LL AUTOMATICALLY GET THE CLASS AS FIRST ARGUMENT!)

<class '__main__.Child1'>.format(calling child1's format, which does lower)

<class '__main__.Child2'>.format(CALLING CHILD2'S FORMAT, WHICH WILL UP ON ANC.FORMAT)

Lonely static without cls or instance 😭this is a static😭

<__main__.Child1 object at 0x10a824460>.format_instance(msg[:self.keep]='thi')

❌as expected this fails 'Child2' object has no attribute 'added_method' cuz missing method

wannabe_method(<__main__.Child2 object at 0x10a824280>,msg='hey just got added! self gets the instance magically').

❌as expected this fails wannabe_method() missing 1 required positional argument: 'msg' because it only got 1 argument

wannabe_method(FAKE INSTANCE!,msg='hackish work').

❌ oh no! no place for self wont_work_as_method() takes 0 positional arguments but 1 was given

<__main__.Child2 object at 0x10a824220>.format_instance(**************************)

<class '__main__.Child2'>.format(TO UPPERCASE)

<class '__main__.Child1'>.format(to lowercase)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.