Use self.vars in class.method(parameters, self.vars)

Discussion in 'Python' started by caccolangrifata, Jul 22, 2011.

  1. I'm very very new with python, and I have some experience with java
    programming, so probably you guys will notice.
    Anyway this is my question:
    I'd like to use class scope vars in method parameter, something like
    that

    class foo(object):

    __init__(self, len = 9):
    self.__myvar = len

    def foo2(self, len = self_myvar):
    while i < len:
    dosomething


    I want to use optional parameter, so i can use
    myfoo = foo() or myfoo = foo(20)
    and also
    foo.foo2(20) or foo.foo2()

    but in def foo2(self, len = self_myvar):
    ^
    self is undefined, so:
    How can I do this stuff?
     
    caccolangrifata, Jul 22, 2011
    #1
    1. Advertisements

  2. caccolangrifata

    Karim Guest

    I think you did a typo

    it is

    def foo2(self, len = self._myvar):
    while i< len:
    dosomething

    You forget '.' dot between self and _myvar
    By the way in the function header you have only one '_'
    and in the init you have 2 '_'.
    Be careful that's not the same variable and behavior in case you want
    to access it.

    Regards
    Karim
     
    Karim, Jul 22, 2011
    #2
    1. Advertisements

  3. I think what you want to do is this:

    class foo (object):
    def __init__(self, len=9):
    self._len = len
    def foo2(self, len=None):
    if len is None:
    len = self._len
    # ...

    Default arguments are for when you want to use exactly the same object
    each time the function/method is called. If you the object you want to
    use depends on something, you can use this arg=None idiom.
     
    Thomas Jollans, Jul 22, 2011
    #3
  4. Yep! Leaving aside the typos, that's exactly I want to do.
    Thanks!
     
    caccolangrifata, Jul 22, 2011
    #4
  5. That, of course, won't work: the default argument (in this case:
    "self._myvar") is looked up when the function is created, and stored
    with the function. "self" does not exist at that point. (or, if it does,
    it's the wrong "self")
     
    Thomas Jollans, Jul 22, 2011
    #5
  6. Totally OT but others already answered the question...
    class names should start with an uppercase letter:

    class Foo(object):
    1/ you want to add a "def" statement before "__init__"
    2/ the argument name ('len') will shadow the builtin 'len' function
    within this function's scope.

    There are very few reasons to invoke the __name_mangling mechanism.
    Canonically, implementation attributes (ie: not part of the API) are
    written with a *single* leading underscore. Also and FWIW, there's no
    need to "hide" public attributes and add dummy accessors in Python
    since you can turn a plain attribute into a computed one latter
    without breaking client code, so only use _implementation attributes
    if you really mean implementation.

    Most of the time, this is spelled:

    for x in <somesquence>:
    do_something

    Note that range() can provide the required sequence.
    Note that default values for function params are only computed once,
    when the def statement is evaluated. This is a famous gotcha,
    specially if you use some mutable object as default value...

    Also, since neither the class nor - a fortiori - the instance exist
    when the def statement is evaluated, there's no way to make reference
    to the instance at this time.
     
    bruno.desthuilliers, Jul 22, 2011
    #6
  7. as just said, Leaving aside the typos ...
    I have experience in java programming so using function calling
    without () is foolish for me XD, but that a great suggestion
    I do not really already understand the mechanism of using private
    public vars in python.
    yep..when the range is known is better use for right.
     
    caccolangrifata, Jul 22, 2011
    #7
  8. caccolangrifata

    Karim Guest

    You're right. Sure the method header is evaluated first I usually not
    fall in this trap when default is a list but a singleton one with the same
    id.
    I answered too fast, I did not understand if he forget the dot or what.
    And the double '_' in init was strange because he uses only one '_' after.

    Thanks to take time to point that.

    Regards
    Karim
     
    Karim, Jul 22, 2011
    #8
  9. class foo(object):

    def __init__(self, len = 9):
    self.__myvar = len

    def foo2(self, len = self.__myvar):
    while i < len:
    do_something

    that the initial code, "." and "_" forgot
     
    caccolangrifata, Jul 22, 2011
    #9
  10. caccolangrifata

    Karim Guest

    Be careful when using double underscore prefix the variable is "said" to
    be private but in fact you can modify it. It is a convention to say
    don't change it. And to discourage to use it python change its name
    to '_<class name>__myvar' appending the prefix '_<class name>' to it.

    See with your example:

    [email protected]:~$ python
    Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
    [GCC 4.5.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
    '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
    '__str__', '__subclasshook__', '__weakref__', '_foo__myvar', 'foo2']

    In the instance namespace your attribute was transformed in '_foo__myvar'.
    This is a veritable mess when you want to access from outside your class
    this attribute.
    For maintenance when you inherited you have huge coupling NEVER DO THAT
    (advice):
    In case you change the name of your class and reference this attribute
    in external class
    you will end up with huge trouble to change the name in all referenced code.
    With one '_' it says to others well this is my non public variable don't
    use it (this is a convention
    because you can still modify it in python.

    Cheers
    Karim
     
    Karim, Jul 22, 2011
    #10
  11. caccolangrifata

    rantingrick Guest

    WRONG! Class identifiers should use the capwords convention

    * class Foo
    * class FooBar
    * class FooBarBaz

    --------------------------------------------------
    PEP8.Naming_Conventions.Class_Names
    --------------------------------------------------
    Almost without exception, class names use the CapWords convention.
    Classes for internal use have a leading underscore in addition.
    --------------------------------------------------

    Make sure to follow this directive to a "T" because if you don't, i
    can assure you that you will regret it! I would actually change
    "Almost without exception" to "WITHOUT EXCEPTION" myself. Actually in
    RickPy4000 naming conventions are going to be enforced -- follow them
    or die of exceptions.


    *Case in point:*
    Some folks refuse to cap "all" words because they "think" some words
    are actually a single "compound word". And in the real world they are
    correct but in the case sensitve world of programming this can bite
    you in the arse later.

    Consider:
    class Messagebox
    class Listview
    class Combobox
    class ScrolledTextbox

    Now later on when you are writing some code you cannot remember which
    words you capped and which you did NOT cap. Best thing to do is ALWAYS
    cap every word. In other words, be consistent!
    class MessageBox
    class ListView
    class ComboBox
    class ScrolledTextBox

    *school-bell-rings*

    PS: Someone needs to create links in the PEP for faster navigation to
    topic of interest OR we need to create a new module called
    "styleguide.py"
    "Almost without exception, class names use the CapWords convention.
    Classes for internal use have a leading underscore in addition."

    PEP8: http://www.python.org/dev/peps/pep-0008/
     
    rantingrick, Jul 22, 2011
    #11
  12. All CamelCase names start with an uppercase letter. You "WRONG!" is wrong.

    Twat.
     
    Thomas Jollans, Jul 22, 2011
    #12
  13. 2/ the argument name ('len') will shadow the builtin 'len' function
    No function is being called. It's just that if you tried using the len()
    function within that method (where there is a variable called `len'), it
    wouldn't work: Python would take your variable and try to call it, not
    the builtin function object.
    Everything is public.

    self._foo (leading underscore) is, by convention, used for internal
    member variables and methods.

    Two leading underscores are the closest thing there is to "private": The
    name is mangled, and won't be visible to subclasses or external code
    under that name (but there's nothing preventing anybody from changing it)
     
    Thomas Jollans, Jul 22, 2011
    #13
  14. caccolangrifata

    John Gordon Guest

    But those names do, in fact, start with an uppercase letter as Bruno said.

    Perhaps Bruno omitted how the remainder of the name should be handled, but
    he was certainly right about the first letter being capitalized.

    Why did you say he was wrong?
     
    John Gordon, Jul 22, 2011
    #14
  15. It's Ranting Rick. Why did you expect anything else? :)

    ChrisA
     
    Chris Angelico, Jul 22, 2011
    #15
  16. caccolangrifata

    rantingrick Guest


    I'll admit my yelling the word "WRONG" may have been interpreted as me
    suggesting that bruno was completely wrong. Bruno is correct about all
    class identifiers starting with a capital letter HOWEVER if he just
    stops at that point and does not explain the "CapWords convention"
    lots of people may start down the road of a foolish consistency.

    My chastisement of Bruno was only on the grounds of him failing to
    offer the required amount of information to a new python programmer.
    We should ALWAYS remove any ambiguities from our statements to new
    users AND we should always link to the PEP8 when these type of style
    questions come up.

    It is SO very important that WE as a community are consistent in our
    syntactical conventions. For me PEP8 does not go far enough and very
    soon i will draft a "PyWart Expose" concerning the matter.
     
    rantingrick, Jul 22, 2011
    #16
  17. Think that you can call you class as you want.

    If you use CamelCase notation than you are pro programmer?

    These are just conventions for better code reading and understanding,
    if I wanna call mYCLasS() python don't report an error, so I think
    it's useless discuss in that thread about that stuff.
     
    caccolangrifata, Jul 22, 2011
    #17
  18. In other words, every new Python programmer must be sat down with a
    massive manual and ordered to read it until his eyes bleed and he goes
    off and finds some other language to use.

    Is it better for Python if we ensure that all Python code written is
    written perfectly, or is it better to allow people to write code, use
    code, learn code, and then later on, learn to do things more
    conveniently?

    You really need to learn the difference between language requirements
    and stylistic advice. You're trying to turn the latter into the
    former, but there is a good reason for language flexibility.

    Why am I responding to these trolls? And why am I being so polite as I
    do so? Rick, put up or shut up. Get some code down or quit talking.
    (Oh and those are not exclusive ors.)

    ChrisA
     
    Chris Angelico, Jul 22, 2011
    #18
  19. caccolangrifata

    Chris Torek Guest

    Others have answered what appears to have been your actual
    question. Here's an example of using an actual "class scope
    variable".

    (Note: I have a sinus headache, which is probably the source
    of some of the weirder names :) )

    class Florg(object):
    _DEFAULT_IPPY = 17

    @classmethod
    def set_default_ippy(cls, ippy):
    cls._DEFAULT_IPPY = ippy

    def __init__(self, name, ippy = None):
    if ippy is None:
    ippy = self.__class__._DEFAULT_IPPY
    self.name = name
    self.ippy = ippy

    def zormonkle(self):
    print('%s ippy = %s' % (self.name, self.ippy))

    def example():
    flist = [Florg('first')]
    flist.append(Florg('second'))
    flist.append(Florg('third', 5))
    Florg.set_default_ippy(-4)
    flist.append(Florg('fourth'))
    flist.append(Florg('fifth', 5))

    for florg in flist:
    florg.zormonkle()

    if __name__ == '__main__':
    example()
     
    Chris Torek, Jul 22, 2011
    #19
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.