newbie - integer variable with leading zero for os.makedirs

Bengt Richter bokr at oz.net
Tue Dec 2 01:43:19 EST 2003


On 1 Dec 2003 21:12:57 -0800, jtoher at cyllene.uwa.edu.au (james) wrote:

>I'm using python 2.3 and 2.2 on Mac OSX 10.3.1
>
>My script creates directories from its input using os.makedirs 
>
>This from http://www.python.org/doc/2.3.2/lib/os-file-dir.html:
>
>  makedirs(  path[, mode])
>  Recursive directory creation function. Like mkdir(), but makes
>  all intermediate-level directories needed to contain the leaf
>  directory...
>  The default mode is 0777 (octal)...
>
>My text input specifies the mode as a string - '750', for example.  I
>want to convert the string input to an integer variable for use by
>os.makedirs.
>
>makedirs works fine when I use a literal like 0750, but my problem is
>setting a variable to that kind of value.  int('0750') converts the
>string from ascii to integer, but loses the first zero padding.
It's not that it "loses" it, it's that it is ignoring it as an octal base indication,
and converting with base 10:
 >>> int('0750')
 750
 
>Without the leading zero os.makedirs makes a mess of the permissions
>when it creates the path.
>
>I've tried:
>
>permission = int('750', 8)
That was fine. You converted the string using base 8.
 >>> int('750', 8)
 488
This 488 is a decimal printed representation of what the binary number is.
If you want to see its value represented in octal again in *string* format,
then you call oct with that number, and get a string back.
 >>> oct(488)
 '0750'

If you want to see it in hex as a string, it's
 >>> hex(488)
 '0x1e8'

But the number you get from the bare 0750 literal that worked is

 >>> 0750
 488

The same binary number (judging by the decimal representation (488) that's being printed).

>mode = oct(permission)
you don't want this. If you want to bind the value to the name 'mode',
you could write

 mode = permission

or skip the 'permission' symbol, and just write

 mode = int('750', 8)

>
>but this returns an octal string '0755' and os.makedirs barfs again. 
>It really wants an integer and it really wants that leading zero.  How
It wants the integer, but you have a misconception about 'leading zero'.
The leading zero you are looking at is in a printed string, not in the corresponding
binary. The binary integer is probably a 32-bit integer, unless you have a 64-bit machine.
You would need 11 octal digits besides the zero prefix to represent all the 'leading zeroes'
in that. E.g.,
 >>> '%012o'%488
 '000000000750'

Entered plain:
 >>> 000000000750
 488

>can I assign a number with a leading zero to an integer variable?

Just assign the integer you get from the conversion, e.g.,
 >>> a = 0750
 >>> b = int('750', 8)
 >>> a==b
 True

So you can pass either a or b where you passed 0750 successfully before.
Or use mode in place of a or b and pass that.

There is an important principle behind this trivial stuff: The entities involved
in programming are generally abstract, but we have to have concrete representations
for them. The abstraction behind '0755' embedded without quotes in a Python source
code context where it will be interpreted as a literal is the same abstraction that
would be behind '488' without quotes in the same place, or '0x1e8'. These are three
different character sequences representing the same thing. The leading zero you were
looking at is a zero in the character sequence representation. The fact that there is
no 'x' immediately following means it was an octal representation (if put in a literal
source context). If put in a string literal (with actual quotes making it a source
representation  of a string) then you can pass that string to int(), but int() converts
using base 10 unless told otherwise. And '0750' is valid as a decimal with the same value
as '750' so the conversion from string to binary integer succeeds and gives the value 750.

When you write a = int('0750',8) you are writing a Python source representation of an
assignment statement. It's a sequence of characters, like any other source line, and
it's a _representation_ of something executable. All the parts have to be converted into
other representations, many things through multiple stages of different representation,
until finally it's code in some context, and gets executed. Which means more looking at
representations and and modifying other representations, and on and on.

Keep in mind the difference between a thing and its many possible representations.
IME, it helps in understanding stuff one comes across in programming (and maybe life ;-).

Ceci n'est pas une pipe, it says on Magritte's painting, which depicts a pipe.
(http://aux.planetmath.org/files/objects/3112/tensor-pipe.jpg)

Regards,
Bengt Richter




More information about the Python-list mailing list