Global in multiple files

Roman Suzi rnd at onego.ru
Sun Jun 10 22:45:51 EDT 2001


On 10 Jun 2001, Artur Skura wrote:

>On Sun, 10 Jun 2001 21:55:17 +0400 (MSD), Roman Suzi <rnd at onego.ru> wrote:
>>On 10 Jun 2001, Artur Skura wrote:
>>
>>>>Why do you need global variable in the OOP design anyway?
>>>
>>>I knew you would say that! ;)
>>
>>Yes, of course. Because in True Object Design there is no place for
>>anything global.

that was an irony...

>You have to make some class instance of which will manage
>>userlist.
>Mhm. It seems a little too much overhed for a simple list of users.

What if one day you decide to use threads and userlist is to be shared.
How do you manage your list without breaking it then? But if some object
will be in charge of this resource, it will be much-much easier. You will
need blocking written only once.

>The problem is I need it in many places. So even if I create class
>ManageUsers, set userlist=ManageUsers(), then userlist.add(user),
>it will not solve my problem - it might solve for one class only,

Why? You can have userlist static, if you want to:

--- user_manager.py
class UserManager:
  userlist = []
  def __init__(): ...
  def add(): ...
  def poll(self, func ...):
  def get(self): ...
  def iterate(self): ...


--- other module

import user_manager

class TS:
  userlist = user_manager.UserManager()
  ...

>so probably I need to rearange everything.

Not much. As a bonus you will get proper defined operations on
userlist.

>>>I just want to keep this one little global, userlist, in order
>>>not to do some strange acrobatics later. It's clean, simple,
>>>keeps the number of arguments to pass to ther functions small etc.
>>After seven years of trial and error I could say that I begin to
>>understand OOP ;-)
>>
>>I thought that way about arguments too. It only says that your object
>>design is not done right way. (It usually happens when it's first try
>>anyway).
>
>The problem is how to do it in this case? It seems this is not
>exactly within the scope of this group. But the necessity of
>having userlist available from (almost) everywhere seems still
>obvious to me.

Then let every class to have it (as I show above, for example).

It is also probably that places it is used "everywhere"
are natural to be included in UserManager class.

OOP is about regrouping code according to entities.

For example, userlist is IMHO natural container for
TS_User's. But it seems you need more than
just contain list of users: you do other operations
on the list: poll users, add users (more complex than
just list.append()).

>>>In this case it fits perfectly. I need to acces userlist from any place,
>>>any moment.
>>
>>Maybe some object could be used to represent the functionality with a
>>proper method. For example, AuthoriseUser(). It's a singleton in your
>>situation. But if later you decide to have more userlists, you could add
>>it to authorisation chain.
>
>No, that part of the code (authorisation etc.) is not important now.
>It all will be rewritten, anyway. But I need to be able to know
>the value of userlist from within instances of TS_Command.Handle(),
>also from my main module, and - because the project is a little
>specific - from TS_System and maybe some other classes.
>So some solution would be to pass userlist as an argument of TS_Command
>instance, but somehow it won't work.


>>>OK, suppose I want to do away with global userlist.
>>>I want to pass it to TS_Command instance. Will it work? No. Why?
>>
>>You still think in terms of structural design. Even modular design already
>>has some precautions against globals. Objects are here to completely
>>eliminate the problem.

Only environment (may also be seen as special object) could be
global. Everything else under the sun isn't ;-)

>Tell me how :) I think maybe I', stuck against some exception
>- I really need this list everywhere...

It's interesting, that everywhere could suffer some
drastical rearrangements if you do it in objects.

Small script could bloat. OOP is a code-compressor only when the
complexity is large enough. just like file compressors necessary enlarge
little files (and most of other files too), to be able to compress some of
the files.

>>>I have no idea... You see, I don't want to stick fanatically to my
>>>global, any solution is fine, provided that I can split my code
>>>and see it working as before, when it was all in one file.
>>>This 'userlist' is my last obstacle.
>>
>>It's not. It's just first iteration of object analysis/design/programming
>>you did. (In fact, your classes has hard-coded many things. Probably you
>>will want to change this in the future.)
>
>For sure - I'm jus experimeting, it will al be rewritten, maybe
>in another language, I just want to check out different ways
>(Ruby seems elegant, also I spare some finger-gimnastics when
>I have to change indentation of a whole function only because I
>added one condition etc.)

It's not a problem: you can use Python-aware text editor
or editor with python mode. For code to be readable
indentation is usually a must. So, you indent anyway.

>>It's real fun to return to the same design after some time
>>and look at it critically.
>>
>>Thus, I do not critisize you here. I am trying to express what I myself
>>felt when I tried to reimplement something with objects. At first try
>>you have objects wrong. (This is seen from the amount of cross-usages).
>>
>>It's a painful process which decreeses quality of the code at first. But
>>then it starts to pay off. Bad object design is worse than bad structural
>>one, someone said, but good OD is better than good structural.
>>
>>Try to rethink your design. Maybe your code will have other
>>classes than you have now, and will be less lines.
>
>Could you suggest some good books about OO?
>I want to make things easy for someone who might want to add
>functionality to that code, so it must not be ugly.

Try "OOP tutorial" on google.com

>(BTW I would like to thank other people for pointing out the
>possibility of having global.py module etc. Yes, it solves my
>problem for now, but maybe I should really redesign it as Roman
>suggest to eliminate the need. No, I still don't know how :))

Some hints:


TS_Command could be rearranged to provide generic way to
add new commands. For example,

class TS_Command:
  ...

class TS_ls(TS_Command):
  name = "ls"
  def __init__(self...):
  def do(self, args):
    # ls implementation

class TS_pwd(TS_Command):
  name = "pwd"
  def __init__(self...):
  def do(self, args):
    # ls implementation

...

Or at least make

if cond1:
  ...
elif cond2:
  ...

to make your code more effective.

I have not understood what for do you have TS_fs class.
It's just two utilities which could be fine in separate module,
without making a class.

*

I think that probably it's simpler to start from
structural version again.

Your example is not large enough to bother with classes/
objects unless you plan to make it a module for many developers
or plan to grow it into more elaborate system. Of course,
this is good as exercise in OOA/D/P.

I hope my hints help to refine the code.

>Regards,
>Artur

Sincerely yours, Roman Suzi
-- 
_/ Russia _/ Karelia _/ Petrozavodsk _/ rnd at onego.ru _/
_/ Monday, June 11, 2001 _/ Powered by Linux RedHat 6.2 _/
_/ "Useless Invention: Fur sink." _/





More information about the Python-list mailing list