Question about Object Oriented + functions/global vars?
bruno modulix
onurb at xiludom.gro
Tue Jun 7 05:17:35 EDT 2005
flamesrock wrote:
> ok, so to my knowledge, object oriented means splitting something into
> the simplest number of parts and going from there.
So you may want to refine your knowledge. What you're talking about is
top-down functional decomposition, and it's almost the opposite of OO.
<overly-simplified>
OO is about interacting objects. An object is defined by an identity, a
state, a behaviour, and (even if implicitely) an interface. Objects do
interact by sending messages to each others. The interface of a given
object is the list of *what* messages this object understands (ie: can
respond to). The behavior is defined by *how* a given object responds to
messages (different objects can respond differently to the same message,
and a given object may respond differently to the same message according
to it's current state). The state is made up of the object's internals
vars.
</overly-simplified>
> But the question is-
> when is it enough?
>
> For example I have the following code:
>
> #def put_file(file_id, delete=False):
> # """ Function to put the file on the FTP Server
> # """
> # print "["+file_id+"] FTP for this file started"
> # print "[" + file_id + "] Connecting to machine " + global_addr
Where does this 'global_addr' var come from ?
> # ftp_pool = FTP_pool(file_id,1,40,global_uid,global_pwd)
idem for global_uid and global_pwd. And what are those magic numbers 1
and 40 ?
> # print 'in put_file'
> # try:
> # ftp = ftplib.FTP(global_addr)
> # ftp.login(global_uid, global_pwd)
> # print ftp.getwelcome() +'\n'
> # ftp.cwd(global_ftp_loc)
>
>># ext = os.path.splitext(file_id)[1]
>># if ext not in (".sc4", ".snpickle"):
>># ftp.storlines("STOR " + file_id, open(file_id))
>># else:
>># ftp.storbinary("STOR " + file_id, open(file_id, "rb"), 1024)
>
> # ftp.quit()
> # ftp_pool.close_all()
> # except:
Take care of too-large-except-clause. Here it's ok since you re-raise
the exception, but this is usually a bad practice to not specify the
exception class(es) you want to catch. Hint: sys.exit() works by raising
SystemExit.
> # ftp_pool.close_all()
> # print "[" + file_id + "]Unable to access FTP location"
> # print "[" + file_id + "]Error:" + str(sys.exc_info()[0]) + " "
> + str(sys.exc_info()[1])
> # upload_status[file_id] = "FAILED"
Where does this upload_status comes from ?
> # raise
> # else:
> # print "[" + file_id + "] FTP for file completed"
> # upload_status[file_id] = "SUCCESS"
>
> would the lines with '>#' best be split up into a seperate function,
> for example:
>
> #def upload(ftp, file):
dont use 'file', it shadows the builtin file class.
> # ext = os.path.splitext(file)[1]
> # if ext in (".txt", ".htm", ".html"):
> # ftp.storlines("STOR " + file, open(file))
> # else:
> # ftp.storbinary("STOR " + file, open(file, "rb"), 1024)
Nope.
<IMHO> The calling code should not have to worry about this. This should
be a responsability of some object(s) abstracting the file, and should
be implemented as different behaviors (using text or binary) in response
to the same message.</IMHO> In short, this could look like:
the_file = FtpFileDescriptor(path)
try:
# the_file objects knows if it must use text or binary.
# we, as client, just don't care about this gory detail.
the_file.store()
except MyFtpUploadError, e:
# TODO
pass
>
> and then doing the call 'upload(file_id)', or is it a better practice
> to leave things the way they were? I'm confused.
>
> Finally, is it considered 'un-object-oriented' in python to have
> functions inside a module that are called by objects (ie the upload
> function above) and/or use global variables in combination?
<disgression>
In Python, everything's an object (well... almost everything). At
runtime, a module is an object :
>>> ftplib
<module 'ftplib' from '/usr/lib/python2.3/ftplib.pyc'>
>>> ftplib.__class__
<type 'module'>
>>> ftplib.__class__.__name__
'module'
module-level 'functions' are methods of the given module object, and
'global' vars (the term 'global' is somewhat misleading, since it reaaly
means 'module-level') are attributes of the module object.
</disgression>
Now what makes the difference between OO and non-OO is not the use of
classes, objects etc, but how you *design* your program. Your code
snippet makes use of OO features (classes, objects etc), but is typical
of procedural style. Not because you use 'module-level' functions and
vars, but because there's no abstraction, no separation of concerns and
responsabilities.
> -thanks in advance
HTH (not sure, but...)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list