Functions, methods, and how many arguments do I have to give them?










-3















Why do the following lines give me the same result?



str.upper('hello')


and



'hello'.upper()


I tried to do the same with list.append but got a TypeError.



list.append([1]) 


Is the str type in python overloaded? How can this be achieved by writing a class/function? I would appreciate an example.



Thanks,



RP.










share|improve this question



















  • 4





    at which list you do expect to append 1?

    – Gsk
    Nov 15 '18 at 14:25






  • 2





    What would your list.append([1]) append where?

    – Christian König
    Nov 15 '18 at 14:25






  • 2





    What's the relation between your first example for upper cases and append an integer to a list?

    – Ssein
    Nov 15 '18 at 14:29






  • 1





    "How can this be achieved by writing a class/function?" How can what be achieved? It's not at all clear what you are asking for.

    – Ayxan
    Nov 15 '18 at 14:38






  • 1





    This question is only trivial on the surface. +1

    – timgeb
    Nov 15 '18 at 15:36















-3















Why do the following lines give me the same result?



str.upper('hello')


and



'hello'.upper()


I tried to do the same with list.append but got a TypeError.



list.append([1]) 


Is the str type in python overloaded? How can this be achieved by writing a class/function? I would appreciate an example.



Thanks,



RP.










share|improve this question



















  • 4





    at which list you do expect to append 1?

    – Gsk
    Nov 15 '18 at 14:25






  • 2





    What would your list.append([1]) append where?

    – Christian König
    Nov 15 '18 at 14:25






  • 2





    What's the relation between your first example for upper cases and append an integer to a list?

    – Ssein
    Nov 15 '18 at 14:29






  • 1





    "How can this be achieved by writing a class/function?" How can what be achieved? It's not at all clear what you are asking for.

    – Ayxan
    Nov 15 '18 at 14:38






  • 1





    This question is only trivial on the surface. +1

    – timgeb
    Nov 15 '18 at 15:36













-3












-3








-3








Why do the following lines give me the same result?



str.upper('hello')


and



'hello'.upper()


I tried to do the same with list.append but got a TypeError.



list.append([1]) 


Is the str type in python overloaded? How can this be achieved by writing a class/function? I would appreciate an example.



Thanks,



RP.










share|improve this question
















Why do the following lines give me the same result?



str.upper('hello')


and



'hello'.upper()


I tried to do the same with list.append but got a TypeError.



list.append([1]) 


Is the str type in python overloaded? How can this be achieved by writing a class/function? I would appreciate an example.



Thanks,



RP.







python string list function methods






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 14:48









timgeb

51.2k116794




51.2k116794










asked Nov 15 '18 at 14:23









rp12808rp12808

353




353







  • 4





    at which list you do expect to append 1?

    – Gsk
    Nov 15 '18 at 14:25






  • 2





    What would your list.append([1]) append where?

    – Christian König
    Nov 15 '18 at 14:25






  • 2





    What's the relation between your first example for upper cases and append an integer to a list?

    – Ssein
    Nov 15 '18 at 14:29






  • 1





    "How can this be achieved by writing a class/function?" How can what be achieved? It's not at all clear what you are asking for.

    – Ayxan
    Nov 15 '18 at 14:38






  • 1





    This question is only trivial on the surface. +1

    – timgeb
    Nov 15 '18 at 15:36












  • 4





    at which list you do expect to append 1?

    – Gsk
    Nov 15 '18 at 14:25






  • 2





    What would your list.append([1]) append where?

    – Christian König
    Nov 15 '18 at 14:25






  • 2





    What's the relation between your first example for upper cases and append an integer to a list?

    – Ssein
    Nov 15 '18 at 14:29






  • 1





    "How can this be achieved by writing a class/function?" How can what be achieved? It's not at all clear what you are asking for.

    – Ayxan
    Nov 15 '18 at 14:38






  • 1





    This question is only trivial on the surface. +1

    – timgeb
    Nov 15 '18 at 15:36







4




4





at which list you do expect to append 1?

– Gsk
Nov 15 '18 at 14:25





at which list you do expect to append 1?

– Gsk
Nov 15 '18 at 14:25




2




2





What would your list.append([1]) append where?

– Christian König
Nov 15 '18 at 14:25





What would your list.append([1]) append where?

– Christian König
Nov 15 '18 at 14:25




2




2





What's the relation between your first example for upper cases and append an integer to a list?

– Ssein
Nov 15 '18 at 14:29





What's the relation between your first example for upper cases and append an integer to a list?

– Ssein
Nov 15 '18 at 14:29




1




1





"How can this be achieved by writing a class/function?" How can what be achieved? It's not at all clear what you are asking for.

– Ayxan
Nov 15 '18 at 14:38





"How can this be achieved by writing a class/function?" How can what be achieved? It's not at all clear what you are asking for.

– Ayxan
Nov 15 '18 at 14:38




1




1





This question is only trivial on the surface. +1

– timgeb
Nov 15 '18 at 15:36





This question is only trivial on the surface. +1

– timgeb
Nov 15 '18 at 15:36












4 Answers
4






active

oldest

votes


















7














list.append takes two arguments - the list to modify and the element to append. So you need to do it like this:



ls = [1]
list.append(ls, 2)


which is equivalent to the much more popular:



ls.append(2)





share|improve this answer
































    6














    str.upper and list.append are both functions.



    str.upper takes one argument.



    >>> str.upper('test')
    'TEST'


    list.append takes two arguments.



    >>> my_list = 
    >>> list.append(my_list, 1)
    >>> my_list
    [1]


    str.upper and list.append (like other functions) are also non-data-descriptors with a __get__ method which in this context has two implications:



    1. When you access the function through the class via the dot notation (str.upper, list.append) the function's __get__ method (i.e. string.upper.__get__ and list.append.__get__) is called but it returns just the function itself.

    2. When you access the function through an instance (my_string.upper, my_list.append) the function's __get__ method is called and it will return a new callable acting like the original function, but with whatever was "in front of the dot" automatically passed as the first argument. .

    That's why you need to pass 1 - 1 = 0 arguments when calling my_string.upper() and 2 - 1 = 1 argument when calling my_list.append(1).



    >>> 'my_string'.upper()
    'MY_STRING'
    >>>
    >>> my_list =
    >>> my_list.append(1)
    >>> my_list
    [1]


    You could even get these modified callables (methods) by explicitly calling __get__ and passing the argument to be bound (what has been before the dot) as its argument.



    >>> my_string = 'my_string'
    >>> upper_maker = str.upper.__get__(my_string)
    >>> upper_maker()
    'MY_STRING'
    >>>
    >>> my_list =
    >>> appender = list.append.__get__(my_list)
    >>> appender(1)
    >>> my_list
    [1]


    Finally, here's a short example demonstrating how descriptor instances can detect whether they are being accessed via their owner-class or via an instance.



    class Descriptor:
    def __get__(self, instance, owner_class):
    if instance is None:
    print('accessed through class')
    # list.append.__get__ would return list.append here
    else:
    print('accessed through instance')
    # list.append.__get__ would build a new callable here
    # that takes one argument x and that internally calls
    # list.append(instance, x)

    class Class:
    attribute = Descriptor()

    Class.attribute # prints 'accessed through class'

    instance = Class()
    instance.attribute # prints 'accessed through instance'





    share|improve this answer

























    • Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

      – Idlehands
      Nov 15 '18 at 14:50







    • 1





      @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

      – timgeb
      Nov 15 '18 at 15:16












    • Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

      – Idlehands
      Nov 15 '18 at 15:23












    • @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

      – timgeb
      Nov 15 '18 at 15:33


















    3














    Quoting Dave Kirbys answer from Relationship between string module and str:




    There is some overlap between the string module and the str type,
    mainly for historical reasons. In early versions of Python str objects
    did not have methods, so all string manipulation was done with
    functions from the string module. When methods were added to the str
    type (in Python 1.5?) the functions were left in the string module for
    compatibility, but now just forward to the equivalent str method.



    However the string module also contains constants and functions that
    are not methods on str, such as formatting, character translation etc.







    share|improve this answer


















    • 2





      this is probably the best answer one can give here. Don't understand the -1. Well done.

      – Ev. Kounis
      Nov 15 '18 at 14:33











    • It probably got downvoted because it was literally a straight quote from another answer in a related thread.

      – Idlehands
      Nov 15 '18 at 14:48


















    2














    There is nothing at all magical going on with str (except that we have a nice syntactic shortcut to creating one using ""). You can write a class that behaves like str and list to see more clearly what is happening here.



    class MyClass():
    def __init__(self, arg):
    self.val=str(arg)

    def do_thing(self):
    self.val = "asdf"

    def do_thing_with_arg(self, arg):
    self.val = "asdf " + str(arg)

    def __repr__(self):
    return self.val


    my_thing = MyClass("qwerty")

    # this is like 'hello'.upper()
    my_thing.do_thing()
    print(my_thing)
    # it prints 'asdf'

    my_thing = MyClass("qwerty")

    # this is like str.upper('hello')
    MyClass.do_thing(my_thing)
    print(my_thing)
    # it prints 'asdf'

    my_thing = MyClass("qwerty")

    # this is like my_list.append('qwerty')
    my_thing.do_thing_with_arg('zxcv')
    print(my_thing)
    # it prints 'asdf zxcv'

    my_thing = MyClass("qwerty")

    # this is like list.append(my_list, 'qwerty')
    MyClass.do_thing_with_arg(my_thing, 'zxcv')
    print(my_thing)
    # it prints 'asdf zxcv'


    The short version is, you're invoking what looks like an "instance method" on a class, but you are supplying the instance ('self') yourself as the first argument to the function call.






    share|improve this answer
























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53321546%2ffunctions-methods-and-how-many-arguments-do-i-have-to-give-them%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      7














      list.append takes two arguments - the list to modify and the element to append. So you need to do it like this:



      ls = [1]
      list.append(ls, 2)


      which is equivalent to the much more popular:



      ls.append(2)





      share|improve this answer





























        7














        list.append takes two arguments - the list to modify and the element to append. So you need to do it like this:



        ls = [1]
        list.append(ls, 2)


        which is equivalent to the much more popular:



        ls.append(2)





        share|improve this answer



























          7












          7








          7







          list.append takes two arguments - the list to modify and the element to append. So you need to do it like this:



          ls = [1]
          list.append(ls, 2)


          which is equivalent to the much more popular:



          ls.append(2)





          share|improve this answer















          list.append takes two arguments - the list to modify and the element to append. So you need to do it like this:



          ls = [1]
          list.append(ls, 2)


          which is equivalent to the much more popular:



          ls.append(2)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 15 '18 at 14:32









          Ev. Kounis

          11.3k21751




          11.3k21751










          answered Nov 15 '18 at 14:29









          pelyapelya

          3,38311819




          3,38311819























              6














              str.upper and list.append are both functions.



              str.upper takes one argument.



              >>> str.upper('test')
              'TEST'


              list.append takes two arguments.



              >>> my_list = 
              >>> list.append(my_list, 1)
              >>> my_list
              [1]


              str.upper and list.append (like other functions) are also non-data-descriptors with a __get__ method which in this context has two implications:



              1. When you access the function through the class via the dot notation (str.upper, list.append) the function's __get__ method (i.e. string.upper.__get__ and list.append.__get__) is called but it returns just the function itself.

              2. When you access the function through an instance (my_string.upper, my_list.append) the function's __get__ method is called and it will return a new callable acting like the original function, but with whatever was "in front of the dot" automatically passed as the first argument. .

              That's why you need to pass 1 - 1 = 0 arguments when calling my_string.upper() and 2 - 1 = 1 argument when calling my_list.append(1).



              >>> 'my_string'.upper()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> my_list.append(1)
              >>> my_list
              [1]


              You could even get these modified callables (methods) by explicitly calling __get__ and passing the argument to be bound (what has been before the dot) as its argument.



              >>> my_string = 'my_string'
              >>> upper_maker = str.upper.__get__(my_string)
              >>> upper_maker()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> appender = list.append.__get__(my_list)
              >>> appender(1)
              >>> my_list
              [1]


              Finally, here's a short example demonstrating how descriptor instances can detect whether they are being accessed via their owner-class or via an instance.



              class Descriptor:
              def __get__(self, instance, owner_class):
              if instance is None:
              print('accessed through class')
              # list.append.__get__ would return list.append here
              else:
              print('accessed through instance')
              # list.append.__get__ would build a new callable here
              # that takes one argument x and that internally calls
              # list.append(instance, x)

              class Class:
              attribute = Descriptor()

              Class.attribute # prints 'accessed through class'

              instance = Class()
              instance.attribute # prints 'accessed through instance'





              share|improve this answer

























              • Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

                – Idlehands
                Nov 15 '18 at 14:50







              • 1





                @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

                – timgeb
                Nov 15 '18 at 15:16












              • Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

                – Idlehands
                Nov 15 '18 at 15:23












              • @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

                – timgeb
                Nov 15 '18 at 15:33















              6














              str.upper and list.append are both functions.



              str.upper takes one argument.



              >>> str.upper('test')
              'TEST'


              list.append takes two arguments.



              >>> my_list = 
              >>> list.append(my_list, 1)
              >>> my_list
              [1]


              str.upper and list.append (like other functions) are also non-data-descriptors with a __get__ method which in this context has two implications:



              1. When you access the function through the class via the dot notation (str.upper, list.append) the function's __get__ method (i.e. string.upper.__get__ and list.append.__get__) is called but it returns just the function itself.

              2. When you access the function through an instance (my_string.upper, my_list.append) the function's __get__ method is called and it will return a new callable acting like the original function, but with whatever was "in front of the dot" automatically passed as the first argument. .

              That's why you need to pass 1 - 1 = 0 arguments when calling my_string.upper() and 2 - 1 = 1 argument when calling my_list.append(1).



              >>> 'my_string'.upper()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> my_list.append(1)
              >>> my_list
              [1]


              You could even get these modified callables (methods) by explicitly calling __get__ and passing the argument to be bound (what has been before the dot) as its argument.



              >>> my_string = 'my_string'
              >>> upper_maker = str.upper.__get__(my_string)
              >>> upper_maker()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> appender = list.append.__get__(my_list)
              >>> appender(1)
              >>> my_list
              [1]


              Finally, here's a short example demonstrating how descriptor instances can detect whether they are being accessed via their owner-class or via an instance.



              class Descriptor:
              def __get__(self, instance, owner_class):
              if instance is None:
              print('accessed through class')
              # list.append.__get__ would return list.append here
              else:
              print('accessed through instance')
              # list.append.__get__ would build a new callable here
              # that takes one argument x and that internally calls
              # list.append(instance, x)

              class Class:
              attribute = Descriptor()

              Class.attribute # prints 'accessed through class'

              instance = Class()
              instance.attribute # prints 'accessed through instance'





              share|improve this answer

























              • Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

                – Idlehands
                Nov 15 '18 at 14:50







              • 1





                @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

                – timgeb
                Nov 15 '18 at 15:16












              • Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

                – Idlehands
                Nov 15 '18 at 15:23












              • @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

                – timgeb
                Nov 15 '18 at 15:33













              6












              6








              6







              str.upper and list.append are both functions.



              str.upper takes one argument.



              >>> str.upper('test')
              'TEST'


              list.append takes two arguments.



              >>> my_list = 
              >>> list.append(my_list, 1)
              >>> my_list
              [1]


              str.upper and list.append (like other functions) are also non-data-descriptors with a __get__ method which in this context has two implications:



              1. When you access the function through the class via the dot notation (str.upper, list.append) the function's __get__ method (i.e. string.upper.__get__ and list.append.__get__) is called but it returns just the function itself.

              2. When you access the function through an instance (my_string.upper, my_list.append) the function's __get__ method is called and it will return a new callable acting like the original function, but with whatever was "in front of the dot" automatically passed as the first argument. .

              That's why you need to pass 1 - 1 = 0 arguments when calling my_string.upper() and 2 - 1 = 1 argument when calling my_list.append(1).



              >>> 'my_string'.upper()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> my_list.append(1)
              >>> my_list
              [1]


              You could even get these modified callables (methods) by explicitly calling __get__ and passing the argument to be bound (what has been before the dot) as its argument.



              >>> my_string = 'my_string'
              >>> upper_maker = str.upper.__get__(my_string)
              >>> upper_maker()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> appender = list.append.__get__(my_list)
              >>> appender(1)
              >>> my_list
              [1]


              Finally, here's a short example demonstrating how descriptor instances can detect whether they are being accessed via their owner-class or via an instance.



              class Descriptor:
              def __get__(self, instance, owner_class):
              if instance is None:
              print('accessed through class')
              # list.append.__get__ would return list.append here
              else:
              print('accessed through instance')
              # list.append.__get__ would build a new callable here
              # that takes one argument x and that internally calls
              # list.append(instance, x)

              class Class:
              attribute = Descriptor()

              Class.attribute # prints 'accessed through class'

              instance = Class()
              instance.attribute # prints 'accessed through instance'





              share|improve this answer















              str.upper and list.append are both functions.



              str.upper takes one argument.



              >>> str.upper('test')
              'TEST'


              list.append takes two arguments.



              >>> my_list = 
              >>> list.append(my_list, 1)
              >>> my_list
              [1]


              str.upper and list.append (like other functions) are also non-data-descriptors with a __get__ method which in this context has two implications:



              1. When you access the function through the class via the dot notation (str.upper, list.append) the function's __get__ method (i.e. string.upper.__get__ and list.append.__get__) is called but it returns just the function itself.

              2. When you access the function through an instance (my_string.upper, my_list.append) the function's __get__ method is called and it will return a new callable acting like the original function, but with whatever was "in front of the dot" automatically passed as the first argument. .

              That's why you need to pass 1 - 1 = 0 arguments when calling my_string.upper() and 2 - 1 = 1 argument when calling my_list.append(1).



              >>> 'my_string'.upper()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> my_list.append(1)
              >>> my_list
              [1]


              You could even get these modified callables (methods) by explicitly calling __get__ and passing the argument to be bound (what has been before the dot) as its argument.



              >>> my_string = 'my_string'
              >>> upper_maker = str.upper.__get__(my_string)
              >>> upper_maker()
              'MY_STRING'
              >>>
              >>> my_list =
              >>> appender = list.append.__get__(my_list)
              >>> appender(1)
              >>> my_list
              [1]


              Finally, here's a short example demonstrating how descriptor instances can detect whether they are being accessed via their owner-class or via an instance.



              class Descriptor:
              def __get__(self, instance, owner_class):
              if instance is None:
              print('accessed through class')
              # list.append.__get__ would return list.append here
              else:
              print('accessed through instance')
              # list.append.__get__ would build a new callable here
              # that takes one argument x and that internally calls
              # list.append(instance, x)

              class Class:
              attribute = Descriptor()

              Class.attribute # prints 'accessed through class'

              instance = Class()
              instance.attribute # prints 'accessed through instance'






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 15 '18 at 15:10

























              answered Nov 15 '18 at 14:42









              timgebtimgeb

              51.2k116794




              51.2k116794












              • Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

                – Idlehands
                Nov 15 '18 at 14:50







              • 1





                @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

                – timgeb
                Nov 15 '18 at 15:16












              • Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

                – Idlehands
                Nov 15 '18 at 15:23












              • @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

                – timgeb
                Nov 15 '18 at 15:33

















              • Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

                – Idlehands
                Nov 15 '18 at 14:50







              • 1





                @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

                – timgeb
                Nov 15 '18 at 15:16












              • Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

                – Idlehands
                Nov 15 '18 at 15:23












              • @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

                – timgeb
                Nov 15 '18 at 15:33
















              Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

              – Idlehands
              Nov 15 '18 at 14:50






              Wouldn't str.upper and list.append fall under the category of instance method under the str and list class?

              – Idlehands
              Nov 15 '18 at 14:50





              1




              1





              @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

              – timgeb
              Nov 15 '18 at 15:16






              @Idlehands It's a little word-thinky. If I had to try to be very correct, I would say: str.upper and list.append are functions that return methods when their __get__ method is called with a non-None instance argument - where I would define a method as a callable which partially (i.e. with bound first argument) applies a function defined inside a class.

              – timgeb
              Nov 15 '18 at 15:16














              Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

              – Idlehands
              Nov 15 '18 at 15:23






              Thanks for the clarification, I was genuinely confused because my background is not in comp-sci so terminologies and paradigms are weak spots for me. My understanding was that any functions defined within a class (i.e. a dot preceding its name) is always a method (instance/class/static) hence my original question. In this case I figured str.upper would have been defined similar as class str: def upper(self): where it either runs as instance.upper() or str.upper(instance).

              – Idlehands
              Nov 15 '18 at 15:23














              @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

              – timgeb
              Nov 15 '18 at 15:33





              @Idlehand The whole descriptor topic is hard. Rule of thumb when writing code: my_class.function_name gives you a function to which you must pass all arguments. instance_of_class.function_name gives you a method to which instance_of_class is automatically passed as the first argument (usually named self).

              – timgeb
              Nov 15 '18 at 15:33











              3














              Quoting Dave Kirbys answer from Relationship between string module and str:




              There is some overlap between the string module and the str type,
              mainly for historical reasons. In early versions of Python str objects
              did not have methods, so all string manipulation was done with
              functions from the string module. When methods were added to the str
              type (in Python 1.5?) the functions were left in the string module for
              compatibility, but now just forward to the equivalent str method.



              However the string module also contains constants and functions that
              are not methods on str, such as formatting, character translation etc.







              share|improve this answer


















              • 2





                this is probably the best answer one can give here. Don't understand the -1. Well done.

                – Ev. Kounis
                Nov 15 '18 at 14:33











              • It probably got downvoted because it was literally a straight quote from another answer in a related thread.

                – Idlehands
                Nov 15 '18 at 14:48















              3














              Quoting Dave Kirbys answer from Relationship between string module and str:




              There is some overlap between the string module and the str type,
              mainly for historical reasons. In early versions of Python str objects
              did not have methods, so all string manipulation was done with
              functions from the string module. When methods were added to the str
              type (in Python 1.5?) the functions were left in the string module for
              compatibility, but now just forward to the equivalent str method.



              However the string module also contains constants and functions that
              are not methods on str, such as formatting, character translation etc.







              share|improve this answer


















              • 2





                this is probably the best answer one can give here. Don't understand the -1. Well done.

                – Ev. Kounis
                Nov 15 '18 at 14:33











              • It probably got downvoted because it was literally a straight quote from another answer in a related thread.

                – Idlehands
                Nov 15 '18 at 14:48













              3












              3








              3







              Quoting Dave Kirbys answer from Relationship between string module and str:




              There is some overlap between the string module and the str type,
              mainly for historical reasons. In early versions of Python str objects
              did not have methods, so all string manipulation was done with
              functions from the string module. When methods were added to the str
              type (in Python 1.5?) the functions were left in the string module for
              compatibility, but now just forward to the equivalent str method.



              However the string module also contains constants and functions that
              are not methods on str, such as formatting, character translation etc.







              share|improve this answer













              Quoting Dave Kirbys answer from Relationship between string module and str:




              There is some overlap between the string module and the str type,
              mainly for historical reasons. In early versions of Python str objects
              did not have methods, so all string manipulation was done with
              functions from the string module. When methods were added to the str
              type (in Python 1.5?) the functions were left in the string module for
              compatibility, but now just forward to the equivalent str method.



              However the string module also contains constants and functions that
              are not methods on str, such as formatting, character translation etc.








              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 15 '18 at 14:30









              Christian KönigChristian König

              2,5491121




              2,5491121







              • 2





                this is probably the best answer one can give here. Don't understand the -1. Well done.

                – Ev. Kounis
                Nov 15 '18 at 14:33











              • It probably got downvoted because it was literally a straight quote from another answer in a related thread.

                – Idlehands
                Nov 15 '18 at 14:48












              • 2





                this is probably the best answer one can give here. Don't understand the -1. Well done.

                – Ev. Kounis
                Nov 15 '18 at 14:33











              • It probably got downvoted because it was literally a straight quote from another answer in a related thread.

                – Idlehands
                Nov 15 '18 at 14:48







              2




              2





              this is probably the best answer one can give here. Don't understand the -1. Well done.

              – Ev. Kounis
              Nov 15 '18 at 14:33





              this is probably the best answer one can give here. Don't understand the -1. Well done.

              – Ev. Kounis
              Nov 15 '18 at 14:33













              It probably got downvoted because it was literally a straight quote from another answer in a related thread.

              – Idlehands
              Nov 15 '18 at 14:48





              It probably got downvoted because it was literally a straight quote from another answer in a related thread.

              – Idlehands
              Nov 15 '18 at 14:48











              2














              There is nothing at all magical going on with str (except that we have a nice syntactic shortcut to creating one using ""). You can write a class that behaves like str and list to see more clearly what is happening here.



              class MyClass():
              def __init__(self, arg):
              self.val=str(arg)

              def do_thing(self):
              self.val = "asdf"

              def do_thing_with_arg(self, arg):
              self.val = "asdf " + str(arg)

              def __repr__(self):
              return self.val


              my_thing = MyClass("qwerty")

              # this is like 'hello'.upper()
              my_thing.do_thing()
              print(my_thing)
              # it prints 'asdf'

              my_thing = MyClass("qwerty")

              # this is like str.upper('hello')
              MyClass.do_thing(my_thing)
              print(my_thing)
              # it prints 'asdf'

              my_thing = MyClass("qwerty")

              # this is like my_list.append('qwerty')
              my_thing.do_thing_with_arg('zxcv')
              print(my_thing)
              # it prints 'asdf zxcv'

              my_thing = MyClass("qwerty")

              # this is like list.append(my_list, 'qwerty')
              MyClass.do_thing_with_arg(my_thing, 'zxcv')
              print(my_thing)
              # it prints 'asdf zxcv'


              The short version is, you're invoking what looks like an "instance method" on a class, but you are supplying the instance ('self') yourself as the first argument to the function call.






              share|improve this answer





























                2














                There is nothing at all magical going on with str (except that we have a nice syntactic shortcut to creating one using ""). You can write a class that behaves like str and list to see more clearly what is happening here.



                class MyClass():
                def __init__(self, arg):
                self.val=str(arg)

                def do_thing(self):
                self.val = "asdf"

                def do_thing_with_arg(self, arg):
                self.val = "asdf " + str(arg)

                def __repr__(self):
                return self.val


                my_thing = MyClass("qwerty")

                # this is like 'hello'.upper()
                my_thing.do_thing()
                print(my_thing)
                # it prints 'asdf'

                my_thing = MyClass("qwerty")

                # this is like str.upper('hello')
                MyClass.do_thing(my_thing)
                print(my_thing)
                # it prints 'asdf'

                my_thing = MyClass("qwerty")

                # this is like my_list.append('qwerty')
                my_thing.do_thing_with_arg('zxcv')
                print(my_thing)
                # it prints 'asdf zxcv'

                my_thing = MyClass("qwerty")

                # this is like list.append(my_list, 'qwerty')
                MyClass.do_thing_with_arg(my_thing, 'zxcv')
                print(my_thing)
                # it prints 'asdf zxcv'


                The short version is, you're invoking what looks like an "instance method" on a class, but you are supplying the instance ('self') yourself as the first argument to the function call.






                share|improve this answer



























                  2












                  2








                  2







                  There is nothing at all magical going on with str (except that we have a nice syntactic shortcut to creating one using ""). You can write a class that behaves like str and list to see more clearly what is happening here.



                  class MyClass():
                  def __init__(self, arg):
                  self.val=str(arg)

                  def do_thing(self):
                  self.val = "asdf"

                  def do_thing_with_arg(self, arg):
                  self.val = "asdf " + str(arg)

                  def __repr__(self):
                  return self.val


                  my_thing = MyClass("qwerty")

                  # this is like 'hello'.upper()
                  my_thing.do_thing()
                  print(my_thing)
                  # it prints 'asdf'

                  my_thing = MyClass("qwerty")

                  # this is like str.upper('hello')
                  MyClass.do_thing(my_thing)
                  print(my_thing)
                  # it prints 'asdf'

                  my_thing = MyClass("qwerty")

                  # this is like my_list.append('qwerty')
                  my_thing.do_thing_with_arg('zxcv')
                  print(my_thing)
                  # it prints 'asdf zxcv'

                  my_thing = MyClass("qwerty")

                  # this is like list.append(my_list, 'qwerty')
                  MyClass.do_thing_with_arg(my_thing, 'zxcv')
                  print(my_thing)
                  # it prints 'asdf zxcv'


                  The short version is, you're invoking what looks like an "instance method" on a class, but you are supplying the instance ('self') yourself as the first argument to the function call.






                  share|improve this answer















                  There is nothing at all magical going on with str (except that we have a nice syntactic shortcut to creating one using ""). You can write a class that behaves like str and list to see more clearly what is happening here.



                  class MyClass():
                  def __init__(self, arg):
                  self.val=str(arg)

                  def do_thing(self):
                  self.val = "asdf"

                  def do_thing_with_arg(self, arg):
                  self.val = "asdf " + str(arg)

                  def __repr__(self):
                  return self.val


                  my_thing = MyClass("qwerty")

                  # this is like 'hello'.upper()
                  my_thing.do_thing()
                  print(my_thing)
                  # it prints 'asdf'

                  my_thing = MyClass("qwerty")

                  # this is like str.upper('hello')
                  MyClass.do_thing(my_thing)
                  print(my_thing)
                  # it prints 'asdf'

                  my_thing = MyClass("qwerty")

                  # this is like my_list.append('qwerty')
                  my_thing.do_thing_with_arg('zxcv')
                  print(my_thing)
                  # it prints 'asdf zxcv'

                  my_thing = MyClass("qwerty")

                  # this is like list.append(my_list, 'qwerty')
                  MyClass.do_thing_with_arg(my_thing, 'zxcv')
                  print(my_thing)
                  # it prints 'asdf zxcv'


                  The short version is, you're invoking what looks like an "instance method" on a class, but you are supplying the instance ('self') yourself as the first argument to the function call.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 15 '18 at 14:52

























                  answered Nov 15 '18 at 14:44









                  Rob BrichenoRob Bricheno

                  2,430419




                  2,430419



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53321546%2ffunctions-methods-and-how-many-arguments-do-i-have-to-give-them%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      How to read a connectionString WITH PROVIDER in .NET Core?

                      In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

                      Museum of Modern and Contemporary Art of Trento and Rovereto