On Jan 21, 10:39 am, sl33k_ <ahsanbag...@gmail.com> wrote: > What is namespace? And what is built-in namespace?
tl;dr - Namespaces are sets that contain names. You can think of namespaces as being /like/ boxes. A namespace is therefore an organisational tool, forming a similar purpose to human names & surnames - to identify the right value. (eg "Sparks" is a namespace, "Smith" is another.) The built-in namespace contains all the values which python understands which you _don't_ define that don't have dots in. (eg "int", "True", "None") Looking at this in more detail... We can create a simple namespace using an empty class Family: class Family(object): pass Sparks = Family() Smith = Family() Now clearly Sparks is a name, and Smith is a name. Those names are defined to be two different Family objects/values. (I'm going to deliberately sidestep which namespace "Sparks" and "Smith" sit inside for the moment.) The neat trick is that namespaces are values themselves. In fact the really neat trick is that every value contains a namespace. How do I define a name inside a namespace? Suppose I want to define the name "Michael" as a person inside the Sparks namespace, I can do that like this: class Person(object): pass Sparks.Michael = Person() I can then define the name Michael inside the Smith namespace as well: Smith.Michael = Person() As you can see, I can now refer to two different values with the same name - "Michael". This may look a little like sophistry, so let's suppose the Person we're referring to as Sparks.Michael has an height of 180cm, and a favourite colour of green, and Smith.Michael has a height of 120cm and a favourite colour of 120. In both cases, it makes sense for use to name the height value "height", and name the favourite colour value as "favourite_colour". If we did this though ... height = 180 favourite_colour = "green" height = 120 favourite_colour = "purple" .. python would only remember the most recent value of each. By recognising that every value is a namespace too, we can define those names inside their namespace. Sparks.Michael.height = 180 Sparks.Michael.favourite_colour = "green" Smith.Michael.height = 120 Smith.Michael.favourite_colour = "purple" Now the question that might arise is this: Given I can rewrite the examples above like this... class Family(object): pass class Person(object): pass Sparks = Family() Smith = Family() Sparks_Michael = Person() Smith_Michael = Person() Sparks_Michael_height = 180 Sparks_Michael_favourite_colour = "green" Smith_Michael_height = 120 Smith_Michael_favourite_colour = "purple" ... how is this different from before? Well in this latter version we're not using namespaces to organise our names. This means that if I want to write a function that prints a person's height and favourite colour, it has to look like this: def describe_person(height, favourite_colour): print "The person is", height, "cm tall" print "Their favourite colour is", favourite_colour Then if I want to use this, I have to do this: describe_person(Sparks_Michael_height, Sparks_Michael_favourite_colour) describe_person(Smith_Michael_height, Smith_Michael_favourite_colour) That's quite messy. What does it look like for the namespace version? def describe_person(somePerson): print "The person is", somePerson.height, "cm tall" print "Their favourite colour is", somePerson.favourite_colour describe_person(Sparks.Michael) describe_person(Smith.Michael) describe_person now expects to recieve a single value. Inside that value's namespace it expects to find the values "height" and "colour", and just uses them. As a result, when we use it, rather than passing in each low level attribute (height, colour) we can work at a more convenient level of working with People, and the higher level code becomes clearer. Not only this, if we decide to add an another name to both People ... Sparks.Michael.Pythonista = True Sparks.Michael.Pythonista = False ... we can change describe_person to use this: def describe_person(somePerson): print "The person is", somePerson.height, "cm tall" print "Their favourite colour is", somePerson.favourite_colour if somePerson.Pythonista: print "And they like python!" else: print "They don't know python" Then our code for describing them remains the same: describe_person(Sparks.Michael) describe_person(Smith.Michael) So far so good I hope. Namespaces can contain code as well as basic values. This means we can have ... tiggles = Cat() rover = Dog() jemima = Duck() tiggles.name = "tiggles" rover.name = "rover" jemima.name = "jemima" ... and we can get them all to have some behaviour called "make_noise" defined by the call to Cat(), Dog(), Duck() inside their namespace, which allows us to write: >>> tiggles.make_noise() Meow! >>> rover.make_noise() Woof! >>> jemima.make_noise() Quack! And again that means we can do things like: def describe_animal(animal): print animal.name, "goes", animal.make_noise() And use it like this: >>> describe_animal(tiggles) tiggles goes Meow! >>> describe_animal(rover) rover goes Woof! >>> describe_animal(jemima) jemima goes Quack! In addition to defining namespaces though with classes, I can define them using files. Suppose I have two files: humans.py animals.py And I have another one which is my main program: main.py Furthermore suppose that we decide to put the classes "Family", and "Person" into humans.py We also decide to put "Cat", "Dog" and "Duck into animals.py Inside main.py we need someone of pulling in these names and values in such a way that we can pull them in cleanly, which is where python's "import" function comes in. If we use it like this: import humans import animals This creates two namespaces - humans and animals. The namespace "humans" contains "Family" and "Person", mirroring the fact the functionality is defined in the file humans.py. The namespace "animals" contains "Cat", "Dog" and "Duck", mirroring the fact the functionality is defined in the file animals.py. So our code using this would look like this: Sparks = humans.Family() Smith = humans.Family() Sparks.Michael = humans.Person() Smith.Michael = humans.Person() tiggles = animals.Cat() rover = animals.Dog() jemima = animals.Duck() This can be a bit clunky if you're doing it a lot, so let's revisit where I said "I'm going to deliberately sidestep which namespace "Sparks" and "Smith" sit inside for the moment.". I mentioned that names like: - object - list - int - True .. ie names that you can use without defining are defined inside a namespace built-in to python - which is referred to as the built-in namespace. In particular, if I type: >>> object <type 'object'> >>> int <type 'int'> >>> True True Those names are defined from within the built-in namespace. Where are names like ... Sparks Smith humans animals ... being defined ? Well,it turns out that python (like many other languages) has global values (amongst others), and that global values are accessed via the global namespace: >>> import animals >>> import humans >>> Sparks = humans.Family() >>> Smith = humans.Family() >>> globals() {'animals': <module 'animals' from 'animals.py'>, 'humans': <module 'humans' from 'humans.py'>, 'Smith': <humans.Family instance at 0xb7d343ac>, 'Sparks': <humans.Family instance at 0xb7d3420c>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None} As a result every name sits inside some namespace of some kind. A namespace is used for organising things, and so namespaces can themselves be names and treated as values. Inside a namespace a name can only refer to one value. (Though that value can be a list/tuple/ dict of course, or a piece of behaviour - such as a method or function) Python modules form namespaces. Python classes form namespaces. Python objects form namespaces. In the case of import this also explains the fact there are two forms of import. This version: import humans import animals Simply defines two names, based on the filename containing interesting functionality, which are namespaces containing other names and is used as above. The other looks like this: from humans import Family, Person from animals import Cat, Dog, Duck And still pulls in the same two files, but says "I'm only interested in these 5 things, and please use them to define the names Family, Person, Cat, Dog, Duck" in my global namespace so I can use it like this: Sparks = Family() Smith = Family() Sparks.Michael = Person() Smith.Michael = Person() tiggles = Cat() rover = Dog() jemima = Duck() Which is pretty useful. So what are they? "Namespaces are one honking great idea -- let's do more of those!" :-) Michael. -- http://mail.python.org/mailman/listinfo/python-list