Confusion About Classes

Discussion in 'Python' started by flamesrock, Dec 28, 2004.

  1. flamesrock

    flamesrock Guest

    Hi,

    I've been playing like mad with all sorts of python modules..but I
    still can't seem to get my head around the proper use of a class and
    self. The question stems from this code I made(snippet):
    --------------------------------------------------------------------------------------
    import httplib, ftplib, urllib2, exPyCrypto, score_configurations
    #custom

    class create_server:
    def __init__(self, domain, servername, master_ftpUSER,
    master_ftpPASS, score_ftpUSER, score_ftpPASS, httpport=None,
    ftpport=None):
    self.domain = domain
    if httpport is None:
    self.__httpport = '80'
    else:
    self.__httpport = httpport
    if ftpport is None:
    self.__ftpport = '21'
    else:
    self.__ftpport = ftpport
    if servername is None:
    self.__servername = 'SCORE-SERVER'
    else:
    self.__servername = servername
    self.master_ftpUSER = master_ftpUSER
    self.master_ftpPASS = master_ftpPASS
    self.score_ftpUSER = score_ftpUSER
    self.score_ftpPASS = score_ftpPASS
    self.parser = ConfigParser.ConfigParser()

    def createUniversalConfig(self, score_domain, score_servername,
    score_port):
    ''''''
    self.parser.add_section('score')
    self.parser.set('score', 'domain', self.score_domain)
    self.parser.set('score', 'server', self.score_servername)
    self.parser.set('score', 'server', self.score_port)
    -------------------------------------------------------------------------------------

    The goal is to create a create_server object with the given parameters,
    and then call the method createUniversalConfig() without passing and
    parameters to it. So here are my questions:
    1) in the function parameter heading <<def createUniversalConfig(self,
    score_domain, score_servername, score_port):>> do I need to include
    those parameters as written, like this-- <<def
    createUniversalConfig(self, self.score_domain, self.score_servername,
    self.score_port):>> or not pass any parameters at all?
    2) Do I reference the body of the function like I originally wrote it:
    self.parser.add_section('score')
    self.parser.set('score', 'domain', self.score_domain)
    self.parser.set('score', 'server', self.score_servername)
    self.parser.set('score', 'server', self.score_port)
    or, like this
    self.parser.add_section('score')
    self.parser.set('score', 'domain', score_domain)
    self.parser.set('score', 'server', score_servername)
    self.parser.set('score', 'server', score_port)
    (if the goal is to call the method from the object without any
    parameters)
    3) Can I create a configParser object and just call self.parser.set()
    inside the function without passing it as a parameter, or do I pass it
    as a parameter and call it as parser.set (without the 'self'
    statement.)

    Basically..I'm confused on the proper use of 'self' in this type of
    situation, even after going through all these different tutorials. Any
    ideas?

    -thanks in advance\
     
    flamesrock, Dec 28, 2004
    #1
    1. Advertising

  2. flamesrock wrote:
    > Hi,
    >
    > I've been playing like mad with all sorts of python modules..but I
    > still can't seem to get my head around the proper use of a class and
    > self. The question stems from this code I made(snippet):

    [snip misaligned code]

    When posting to c.l.py it's greatly appreciated if you use spaces
    instead of tabs in your code. Many newsreaders strip out tabs.

    > The goal is to create a create_server object with the given parameters,
    > and then call the method createUniversalConfig() without passing and
    > parameters to it.



    Sounds like you want to write:

    def createUniversalConfig(self):
    ''''''
    self.parser.add_section('score')
    self.parser.set('score', 'domain', self.score_domain)
    self.parser.set('score', 'server', self.score_servername)
    self.parser.set('score', 'server', self.score_port)

    Then you can do something like:

    cs = create_server(... appropriate arguments ...)
    cs.createUniversalConfig()

    However, this will only work if somewhere previously (probably
    __init__), you wrote assignment statements like:

    self.score_domain = ...
    self.score_servername = ...
    self.score_port = ...

    Looking at your code, I don't see that you've done this anywhere. Where
    should score_domain, score_servername and score_port be coming from?
    Are they the same as the 'domain', 'servername' and 'httpport'
    parameters to __init__? If so, you should write your code like:

    def createUniversalConfig(self):
    ''''''
    self.parser.add_section('score')
    self.parser.set('score', 'domain', self.domain)
    self.parser.set('score', 'server', self.servername)
    self.parser.set('score', 'server', self.__httpport)

    As an aside, there's probably no need to prefix your variables with
    double-underscores -- this causes name mangling that's generally not
    necessary in a "we're all consenting adults" language like Python.

    Steve
     
    Steven Bethard, Dec 28, 2004
    #2
    1. Advertising

  3. flamesrock

    M.E.Farmer Guest

    flamesrock wrote:
    [snip]
    > 3) Can I create a configParser object and just call self.parser.set()
    > inside the function without passing it as a parameter, or do I pass

    it
    > as a parameter and call it as parser.set (without the 'self'
    > statement.)
    >
    > Basically..I'm confused on the proper use of 'self' in this type of
    > situation, even after going through all these different tutorials.

    Any
    > ideas?
    >
    > -thanks in advance\

    Ok you have several problems that I see.
    First you are having namespace difficulties.
    I am not sure you 'get it' yet , but if you stay around long enough you
    will ;)
    http://docs.python.org/tut/node11.html

    The proper use of 'self' in a class is its namespace.
    You *have* to pass 'self' to all member functions of a class sp the all
    can have a reference to the namespace.
    It makes it easy to pass data back and forth between functions in a
    class.
    Below is an example of functions calling functions within a class and
    setting attributes, maybe this will clear it up some
    example:
    py>class bla:
    .... def __init__(self):
    .... self.data=0
    .... def setData(self, data):
    .... self.data = data
    .... def getData(self):
    .... return self.data
    .... def nullData(self):
    .... self.setData(None)

    Namespace is one of those crucial concepts you *must* master in python.
    Do a search on google for python namespace, and read, and code, till
    you get it. Master namespace if you have not already. Break out an
    interpreter and hack away. Use dir() around your classes and functions
    and 'see' for yourself what is in them. Do a search on this newsgroup
    for namespace. This has been explained much better than I can.

    Second if you haven't done it yet read up on configparser.
    http://docs.python.org/lib/module-ConfigParser.html
    before implementing a universalconfigwriter/reader you need to know how
    to find previously written sections and options , and add error
    checking etc..
    Especially note this page.
    (Hint this will save you from many long boring hours reinventing all
    this junk and avoiding some eval hack to get the stuff back to the
    right type.)
    If you think I am kidding note others in this newsgroup have been there
    done that, not me of course, I never need documentation ;)
    Hth,
    M.E.Farmer
     
    M.E.Farmer, Dec 28, 2004
    #3
  4. flamesrock

    flamesrock Guest

    Thanks for the responses! And sorry for the late reply, I had to force
    myself away from the computer for a day.

    M.E.Farmer,
    Yes I've been having a little bit of trouble with name spaces, but this
    self thing is actually starting to make sense the more I think about it
    -- I hadn't thought too much about multiple instances of the same class
    for this particular program. The notion of storing data that way makes
    better sense with that example. Coming from a background in the more
    'procedural' languages it was harder to grasp but I think I'm beginning
    to naturally absorb the concept by working my head around these
    examples

    And thanks for the links :) I know this is going to be full of bugs,
    but it would be nice to avoid the more serious ones.

    Steven Bethard,
    First, thanks for fixing up my class. I really appreciate it.

    >Where should score_domain, score_servername and score_port be coming

    from?
    >Are they the same as the 'domain', 'servername' and 'httpport'

    parameters to __init__?
    whoops..heh.. my mistake.
    My original-confused- idea was to use different variable names because
    I didn't want the function to interfere with the classes variables
    directly as I'd be passing the objects variables to itself..if that
    makes any sense. Your way makes me wonder how the heck I came to my
    logifc in the first place

    >As an aside, there's probably no need to prefix your variables with
    >double-underscores -- this causes name mangling that's generally not
    >necessary in a "we're all consenting adults" language like Python.

    Ahh..from an example on the net, I though it was a necessary thing for
    the interpreter..heh. Well not having to certainly simplifies things
    -thanks
     
    flamesrock, Dec 30, 2004
    #4
  5. flamesrock

    M.E.Farmer Guest

    Thanks for the followup,
    I just wanted to mention that you still need to read that stuff thru
    several times, because...
    there are no variables in python (yea I know others will say otherwise
    ;)
    Yep, I said it, none.
    There are NAMES, thats why there are NAMESPACES.
    A name is just a reference or 'handle' to an object, because.....
    everything in python is an OBJECT,(except for names, they are just
    names).
    And before you go and wipe out all those double underscores note that
    python uses double underscores as special methods and other internal
    details( read the docs).
    A quick example is :( yeah it's deja vu)
    py>class bla:
    .... def __init__(self):
    .... self.data=0
    .... def setData(self, data):
    .... self.data = data
    .... def getData(self):
    .... return self.data
    .... def nullData(self):
    .... self.setData(None)
    Not all underscores method names are unnecessary.
    __init__ is a special method that is called by python when we create an
    instance of this class. Most of the double underscore methods are
    special methods and are part of python( later you will see they can be
    used for object customization )
    Now back to self... self is reference to.. well self. Python is
    explicit . A class has it's own namespace so we pass a referance around
    to all it's member functions. when we set an attribute of a class it
    can be done inside or out . Self.data is an example of setting a
    attribute of an object from inside the class ( notice we referance
    ourselves inside the class , because we are assigning the name to that
    namespace.)
    An example of settng attrbutes outside a class:
    bl = bla()
    bl.MyNewData = [1,2,3,4,5]
    dir(bl)

    As a matter of fact a common use of a class is like a container to
    store data.
    class null:
    pass
    a =null()
    a.name = 'mike'
    a.weight= 220
    dir(a)
    del a.name
    Sorry if it is incoherent, I am way past bed time .
    M.E.Farmer
     
    M.E.Farmer, Dec 30, 2004
    #5
  6. M.E.Farmer wrote:
    > there are no variables in python


    While it's true that in Python it's more appropriate to talk about names
    and bindings instead of variables and values, there is a parallel, and
    you can get a fair distance without having to fully convert to the
    names/bindings terminology.

    That being said, understanding this part of Python can aid enormously in
    working with the language. If you'd like to think of it in C terms,
    basically every 'name' in Python is a pointer to a PyObject, and 'names'
    (as pointers) are always passed by value -- that is, you get a copy of
    the pointer, but not a copy of the object.

    > And before you go and wipe out all those double underscores note that
    > python uses double underscores as special methods and other internal
    > details( read the docs).


    Just to clarify, I was only talking about removing leading underscores
    for instance variables, e.g. changing:

    self.__xyz

    to

    self.xyz

    As M.E.Farmer mentioned, you can't remove underscores on special method
    names like __init__. However, when you're declaring an instance
    variable, e.g.:

    self.__xyz = True

    then you're choosing the name here, so you can name it whatever you
    want. The only reason to use leading double-underscores is if you want
    Python to name-mangle the variable so it's not (easily) accessible from
    subclasses. In most cases, this is unnecessary.

    Steve
     
    Steven Bethard, Dec 30, 2004
    #6
  7. flamesrock

    Steve Holden Guest

    Steven Bethard wrote:

    > M.E.Farmer wrote:
    >
    >> there are no variables in python

    [...]
    > As M.E.Farmer mentioned, you can't remove underscores on special method
    > names like __init__. However, when you're declaring an instance
    > variable, e.g.:
    >
    > self.__xyz = True
    >
    > then you're choosing the name here, so you can name it whatever you
    > want. The only reason to use leading double-underscores is if you want
    > Python to name-mangle the variable so it's not (easily) accessible from
    > subclasses. In most cases, this is unnecessary.
    >

    While it's unnecessary in most cases, I'd like to point out that the
    mechanism is mostly to avoid inadvertent clashes in the object namespace.

    So, if you are designing a class explicitly to be subclassed, that's
    when the use of mangled names can pay off.

    Of course, if the subclass implementor actually *does* need access to
    your instance variables they will curse you if you've mangled them.

    unwrapping-that-mangling-isn't-pretti-ly y'rs - steve
    --
    Steve Holden http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
    Holden Web LLC +1 703 861 4237 +1 800 494 3119
     
    Steve Holden, Dec 30, 2004
    #7
  8. flamesrock

    flamesrock Guest

    Well, I took a short excursion into xml for a different part of the
    program, but the class is now finished!! (source below) I have a few
    more questions for you guys.

    1)If I set
    self.serverConfig = file(os.path.join('configuration','score.conf'),
    'w')
    and then go self.serverConfig.close(), is there a way to open it in
    read mode without calling the filename directly? Like
    self.serverConfig.open('r') -which doesn't work BTW- instead of
    open(os.path.join('configuration','score.conf'), 'r')? Using
    open(self.ServerConfig, 'r') doesn't seem to work either.

    2) A problem arose when converting the encoded file back into a string
    for decoding; the \n's seemed to have dissapeared so it returned an
    error when I tried to decode. Is there a way to stop python from
    disposing of those those characters before writing to file?

    3) Is there way to retrieve the timestamp of a file via ftp?

    >>There are NAMES, thats why there are NAMESPACES.
    >>A name is just a reference or 'handle' to an object, because.....
    >>everything in python is an OBJECT,(except for names, they are just
    >>names).

    And
    >>That being said, understanding this part of Python can aid enormously

    in
    >>working with the language. If you'd like to think of it in C terms,
    >>basically every 'name' in Python is a pointer to a PyObject, and

    'names'
    >>(as pointers) are always passed by value -- that is, you get a copy

    of
    >>the pointer, but not a copy of the object.


    Ahhhhh...now *that* makes sense. So dynamically typed variables aren't
    variables at all...but just another term for pointers? cool, I like
    that. And thanks for the examples, guys. Its coming together and I'm
    starting to actually 'get it' :)

    So name mangling basically follows the rules of private and public in
    Java? (I have limited experience in java so don't quote me on that.)

    (Google groups isn't displaying the spaces correctly, so I added four
    *'s = 1 four space indentation..)
    import ftplib, ezPyCrypto, ConfigParser
    import traceback, sys, os
    #-------------------------------------------------------------------------------
    class create_server:
    ****'''Create a create_server object whenever a new server is to be
    added to
    ****the SCORE network.'''
    ****def __init__(self, absCFGpath, domain, servername, master_ftpUSER,
    ****master_ftpPASS, score_ftpUSER='anonymous',
    score_ftpPASS='anonymous',
    ****scorecontact='', maxusers='unlimited',
    httpport='80',
    ****ftpport='21', passivemode=True):
    ********self.domain = domain
    ********self.httpport = httpport
    ********self.ftpport = ftpport
    ********self.servername = servername
    ********self.maxusers = maxusers
    ********self.scorecontact = scorecontact
    ********try:
    ************self.serverConfig =
    file(os.path.join('configuration','score.conf'), 'w')
    ********except:
    ************os.mkdir('configuration')
    ************self.serverConfig =
    file(os.path.join('configuration','score.conf'), 'w')
    ********self.absCFGpath = absCFGpath
    ********self.master_ftpUSER = master_ftpUSER
    ********self.master_ftpPASS = master_ftpPASS
    ********self.score_ftpUSER = score_ftpUSER
    ********self.score_ftpPASS = score_ftpPASS
    ********self.passivemode = passivemode
    ********self.parser = ConfigParser.ConfigParser()

    #-------------------------------------------------------------------------------
    ****def createUniversalConfig(self):
    ********'''Creates the SCORE servers main configuration file.'''
    ********self.parser.add_section('score')
    ********self.parser.set('score', 'domain', self.domain)
    ********self.parser.set('score', 'servername', self.servername)
    ********self.parser.set('score', 'httpport', self.httpport)
    ********self.parser.set('score', 'ftpport', self.ftpport)
    ********self.parser.set('score', 'maxusers', self.maxusers)
    ********self.parser.set('score', 'scorecontact', self.scorecontact)
    ********self.parser.write(self.serverConfig)
    ********self.serverConfig.close()
    ********return open(os.path.join('configuration','score.conf'), 'r')
    #-------------------------------------------------------------------------------
    ****def editUniversalConfig(self, section, key, value):
    ********'''edit the SCORE servers main configuration file.'''
    ********self.serverConfig =
    open(os.path.join('configuration','score.conf'), 'w')
    ********self.parser.set(section, key, value)
    ********self.serverConfig.close
    #-------------------------------------------------------------------------------
    ****def createUSERfile(self):
    ********'''Creates an encrypted ascii public ftp password file that
    clients use
    ********to decode after logging in'''
    ********crypt = ezPyCrypto.key()
    ********userFile = file(os.path.join('configuration','uFile.enc'), 'w')
    ********userFile.write(crypt.encStringToAscii(self.score_ftpUSER))
    ********userFile.close()
    ********userFile = open(os.path.join('configuration','uFile.enc'), 'r')
    ********return userFile
    #-------------------------------------------------------------------------------
    ****def createPASSfile(self):
    ********'''Creates an encrypted ascii public ftp password file that
    clients use
    ********to decode after logging in'''
    ********crypt = ezPyCrypto.key()
    ********passFile = file(os.path.join('configuration','pFile.enc'), 'w')
    ********passFile.write(crypt.encStringToAscii(self.score_ftpPASS))
    ********passFile.close()
    ********passFile = open(os.path.join('configuration','pFile.enc'), 'r')
    ********return passFile
    #-------------------------------------------------------------------------------
    ****def uploadConfigs(self):
    ********'''Uploads the universal config/ftpuser/pass files to the
    correct directories on the site'''
    ********##print "Files:", sys.argv[1:] relic..

    ********print "Logging in..."
    ********ftp = ftplib.FTP()
    ********ftp.set_pasv(self.passivemode) #true if passive, false if
    active
    ********ftp.connect(self.domain, self.ftpport)
    ********print ftp.getwelcome()
    ********try:
    ************try:
    ****************ftp.login(self.master_ftpUSER, self.master_ftpPASS)
    ****************ftp.cwd(self.absCFGpath) #*the SCORE root directory
    ****************print "Currently in:", ftp.pwd()
    ****************print "Uploading..."
    ****************sConfig = self.createUniversalConfig()
    ****************uFile = self.createUSERfile()
    ****************pFile = self.createPASSfile()
    ****************ftp.storlines('STOR score.conf', sConfig)
    ****************try:
    ********************ftp.cwd(self.absCFGpath + '/files')
    ****************except ftplib.error_perm: #*if dir doesn't exist
    ********************ftp.mkd('files')
    ********************ftp.cwd(self.absCFGpath + '/files') #change to
    config directory
    ****************ftp.storlines('STOR uFile.enc', uFile)
    ****************ftp.storlines('STOR pFile.enc', pFile)
    ****************sConfig.close()
    ****************uFile.close()
    ****************pFile.close()
    ****************print "OK"

    ****************print "Files:"
    ****************print ftp.retrlines('LIST')
    ************finally:
    ****************print "Quitting..."
    ************ftp.quit()
    ********except:
    ************traceback.print_exc()
    #-------------------------------------------------------------------------------
    #-------------------------------------------------------------------------------
    #-------------------------------------------------------------------------------
    -thanks,
    flamesrock
     
    flamesrock, Jan 2, 2005
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David

    Classes within classes

    David, Jul 21, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    4,966
    David
    Jul 22, 2005
  2. lonelyplanet999
    Replies:
    1
    Views:
    2,245
    VisionSet
    Nov 13, 2003
  3. Carfield Yim
    Replies:
    1
    Views:
    1,482
    Andrew Thompson
    May 31, 2004
  4. Razvan
    Replies:
    11
    Views:
    932
    Andrew Thompson
    Jul 17, 2004
  5. Johannes Schaub
    Replies:
    1
    Views:
    238
    Alf P. Steinbach /Usenet
    Apr 16, 2011
Loading...

Share This Page