This question already exists:
Closed 10 years ago.
Possible Duplicate:
accessing a python int literals methods
Everything in Python is an object. Even a number is an object:
>>> a=1
>>> type(a)
<class 'int'>
>>>a.real
1
I tried the following, because we should be able to access class members of an object:
>>> type(1)
<class 'int'>
>>> 1.real
File "<stdin>", line 1
1.real
^
SyntaxError: invalid syntax
Why does this not work?
Yes, an integer literal is an object in Python. To summarize, the parser needs to be able to understand it is dealing with an object of type integer, while the statement 1.real confuses the parser into thinking it has a float 1. followed by the word real, and therefore raises a syntax error.
To test this you can also try
>> (1).real
1
as well as,
>> 1.0.real
1.0
so in the case of 1.real python is interpreting the . as a decimal point.
Edit
BasicWolf puts it nicely too - 1. is being interpreted as the floating point representation of 1, so 1.real is equivalent to writing (1.)real - so with no attribute access operator i.e. period /full stop. Hence the syntax error.
Further edit
As mgilson alludes to in his/her comment: the parser can handle access to int's attributes and methods, but only as long the statement makes it clear that it is being given an int and not a float.
a language is usually built in three layers.
when you provide a program to a language it first has to "read" the program. then it builds what it has read into something it can work with. and finally it runs that thing as "a program" and (hopefully) prints a result.
the problem here is that the first part of python - the part that reads programs - is confused. it's confused because it's not clever enough to know the difference between
1.234
and
1.letters
what seems to be happening is that it thinks you were trying to type a number like 1.234 but made a mistake and typed letters instead(!).
so this has nothing to do with what 1 "really is" and whether or not is it an object. all that kind of logic happens in the second and third stages i described earlier, when python tries to build and then run the program.
what you've uncovered is just a strange (but interesting!) wrinkle in how python reads programs.
[i'd call it a bug, but it's probably like this for a reason. it turns out that some things are hard for computers to read. python is probably designed so that it's easy (fast) for the computer to read programs. fixing this "bug" would probably make the part of python that reads programs slower or more complicated. so it's probably a trade-off.]
Although the behaviour with 1.real seems unlogical, it is expected due to the language specification: Python interprets 1. as a float (see floating point literals). But as #mutzmatron pointed out (1).real works because the expression in brackets is a valid Python object.
Update: Note the following pits:
1 + 2j.real
>>> 1.0 # due to the fact that 2j.real == 0
# but
1 + 2j.imag
>>> 3.0 # due to the fact that 2j.imag == 2
You can still access 1.real:
>>> hasattr(1, 'real')
True
>>> getattr(1, 'real')
1
Related
So in our lecture slide on assembly we had:
High-level language data types of C, A, and B determine the correct
circuit from among several choices (integer, floating point) to use to
perform “+” operation
Now in languages like Python, I do not specify the type of the variable. I was wondering how does the language compiles (interprets, I think is what it does) down into assembly and chooses the right circuit?
Thank you
At the interpreter level it's fairly easy to tell the difference between an integer (34), a floating point number (34.24), and a string ("Thirty-Four"). The full list of types can be seen at https://docs.python.org/3/library/stdtypes.html .
Once the type is known, it's easy to tell what operation is needed. A separate function (__add__) is defined for each class, and the interpreter (written in C for standard Python) will do the arithmetic. C is typed and it's (comparatively) easy for the compiler to be translated to machine code.
Every Python variable is a reference to an object. That object includes the type information of the variable. For instance, just walk through a few of the possibilities as we repeatedly reassign the value and type of x "on the fly":
for x in [1, 1.0, "1", [1]]:
print(x, type(x))
Output:
1 <class 'int'>
1.0 <class 'float'>
1 <class 'str'>
[1] <class 'list'>
If you're wondering how Python can tell that 1 is an int and 1.0 is a float, that's obvious from the input string. A language processor typically contains a tokenizer that can discriminate language tokens, and another module that interprets those tokens within the language syntax. int and float objects have different token formats ... as do strings, punctuation, identifiers, and any other language elements.
If you want to learn more about that level of detail, research how to parse a computer language: most of the techniques are applicable to most languages.
As n.m. commented below your post, variables do not have a type in Python. Values do.
As far as how integer vs float is determined when you type the following:
x = 1.5
y = 2
This is determined during the parsing stage. Compiled and interpreted languages actually start off in the same manner.
The general flow when code is sent to an interpreter/compiler is as follows:
[source code] --> lexical analyzer --> [tokens] --> parser --> [abstract syntax tree] -->
The parser step examines tokens like 'x' '=' '1.5' and looks for patterns which indicate different types of literals like ints, floats, and strings. By the time the actual interpreter/compiler gets the abstract syntax tree (tree representation of your program), it already knows that the value stored in x (1.5) is a float.
So just to be clear, this part of the process is conceptually the same for intepreters and compilers.
I'm relatively new to Python but typically find it fairly easy to work out. I've just encountered something, though, which has thrown me a little.
I know that type-checking is not very Pythonic but I'm dealing with user-input and it seems useful here. I expected the following code (in Python 2.7.6) to change a non-relevant input to an empty string, but while trying it out in an interactive interpreter, it returned an unexpected int. Could anybody tell me if this is a special value in Python, or explain why this happens.
I thought that perhaps "code" may be the name of a reserved variable ie. one used internally, but changing the name seemed to have no result.
>>> code = 0134
>>> if type(code) is not int: code =""
...
>>> code
92
I'm sure I can find an alternative way to do what I'm trying to do here, so that's not so much the focus. I'd simply like to work out what's happening with the unexpected int.
Thanks,
Rob
>>> code = 0134
In python 2.7.6 this defines the octal number 132 because of the leading 0. This is equal to the decimal 92.
>>> if type(code) is not int: code =""
If it's not an int then you clear it.
>>> code = 0134
>>> type(code)
<type 'int'>
As you can see you do have an int. When you print it out you get the base-10 representation which is 92.
This particular cause of confusion led to the following PEP http://legacy.python.org/dev/peps/pep-3127/
When a number begins with a 0 in Python, it is interpreted as an octal number. 0134 in octal is 92 in decimal.
I'm not sure why you think the type of that value will not be int. It is an integer.
I realise that this question could be construed as similar to others, so before I start, here is a list of some possible "duplicates" before everyone starts pointing them out. None of these seem to really answer my question properly.
Python string formatting: % vs. .format
"%s" % format vs "{0}".format() vs "?" format
My question specifically pertains to the use of the string.format() method for displaying integer numbers.
Running the following code using % string formatting in the interpreter running python 2.7
>>> print "%d" %(1.2345)
1
Whereas using the string.format() method results in the following
>>> print "{:d}".format(1.2345)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object type 'float'
I was expecting the same behavior in both; for the interpreter to actually convert my floating point number to an integer prior to displaying. I realise that I could just use the int function to convert the floating point number to integer format, but I was looking for the same functionality you get with the %d formatting method. Is there any string.format() method that would do this for me?
The two implementations are quite separate, and some warts in the % implementation were ironed out. Using %d for floats may mask problems in your code, where you thought you had integers but got floating point values instead. Imagine a value of 1.999999 and only seeing 1 instead of 2 as %d truncates the value.
As such, the float.__format__() hook method called by str.format() to do the actual conversion work does not support the d format and throws an exception instead.
You can use the {:.0f} format to explicitly display (rounded) floating point values with no decimal numbers:
>>> '{:.0f}'.format(1.234)
'1'
>>> '{:.0f}'.format(1.534)
'2'
or use int() before formatting to explicitly truncate your floating point number.
As a side note, if all you are doing is formatting a number as a string (and not interpolating into a larger string), use the format() function:
>>> format(1.234, '.0f')
'1'
This communicates your intent better and is a little faster to boot.
There is an important change between 2.7 and 3.0 regarding "automatic type conversion" (coercion). While 2.7 was somehow relatively "relax" regarding this, 3.0 forces you to be more disciplined.
Automatic conversion may be dangerous, as it may silently truncate/reduce some data ! Besides, this behavior is inconsistent and you never know what to expect; until you're faced with he problem. Python 3.0 requires that you specify what you want to, precisely, do !
However, the new string.format() adds some very powerful and useful formatting techniques. It's even very clear with the "free" format '{}'. Like this :
'{}'.format(234)
'{:10}.format(234)
'{:<10}'.format(234)
See ? I didn't need to specify 'integer', 'float' or anything else. This will work for any type of values.
for v in (234, 1.234, 'toto'):
for fmt in ('[{}]', '[{:10}]', '[{:<10d}]', '[{:>10d}]'):
print(fmt.format(v))
Besides, the % value is obsolete and should not be used any more. The new string.format() is easier to use and has more features than the old formatting techniques. Which, IMHO, renders the old technique less attractive.
This question already has answers here:
Best way to convert string to bytes in Python 3?
(5 answers)
Closed 4 years ago.
I am new to python3, coming from python2, and I am a bit confused with unicode fundamentals.
I've read some good posts, that made it all much clearer, however I see there are 2 methods on python 3, that handle encoding and decoding, and I'm not sure which one to use.
So the idea in python 3 is, that every string is unicode, and can be encoded and stored in bytes, or decoded back into unicode string again.
But there are 2 ways to do it:
u'something'.encode('utf-8') will generate b'something', but so does bytes(u'something', 'utf-8').
And b'bytes'.decode('utf-8') seems to do the same thing as str(b'bytes', 'utf-8').
Now my question is, why are there 2 methods that seem to do the same thing, and is either better than the other (and why?) I've been trying to find answer to this on google, but no luck.
>>> original = '27岁少妇生孩子后变老'
>>> type(original)
<class 'str'>
>>> encoded = original.encode('utf-8')
>>> print(encoded)
b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'
>>> type(encoded)
<class 'bytes'>
>>> encoded2 = bytes(original, 'utf-8')
>>> print(encoded2)
b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'
>>> type(encoded2)
<class 'bytes'>
>>> print(encoded+encoded2)
b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x8127\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'
>>> decoded = encoded.decode('utf-8')
>>> print(decoded)
27岁少妇生孩子后变老
>>> decoded2 = str(encoded2, 'utf-8')
>>> print(decoded2)
27岁少妇生孩子后变老
>>> type(decoded)
<class 'str'>
>>> type(decoded2)
<class 'str'>
>>> print(str(b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81', 'utf-8'))
27岁少妇生孩子后变老
>>> print(b'27\xe5\xb2\x81\xe5\xb0\x91\xe5\xa6\x87\xe7\x94\x9f\xe5\xad\xa9\xe5\xad\x90\xe5\x90\x8e\xe5\x8f\x98\xe8\x80\x81'.decode('utf-8'))
27岁少妇生孩子后变老
Neither is better than the other, they do exactly the same thing. However, using .encode() and .decode() is the more common way to do it. It is also compatible with Python 2.
To add to Lennart Regebro's answer There is even the third way that can be used:
encoded3 = str.encode(original, 'utf-8')
print(encoded3)
Anyway, it is actually exactly the same as the first approach. It may also look that the second way is a syntactic sugar for the third approach.
A programming language is a means to express abstract ideas formally, to be executed by the machine. A programming language is considered good if it contains constructs that one needs. Python is a hybrid language -- i.e. more natural and more versatile than pure OO or pure procedural languages. Sometimes functions are more appropriate than the object methods, sometimes the reverse is true. It depends on mental picture of the solved problem.
Anyway, the feature mentioned in the question is probably a by-product of the language implementation/design. In my opinion, this is a nice example that show the alternative thinking about technically the same thing.
In other words, calling an object method means thinking in terms "let the object gives me the wanted result". Calling a function as the alternative means "let the outer code processes the passed argument and extracts the wanted value".
The first approach emphasizes the ability of the object to do the task on its own, the second approach emphasizes the ability of an separate algoritm to extract the data. Sometimes, the separate code may be that much special that it is not wise to add it as a general method to the class of the object.
To add to add to the previous answer, there is even a fourth way that can be used
import codecs
encoded4 = codecs.encode(original, 'utf-8')
print(encoded4)
Python is exhibiting a strange behaviour that I didnt witness before, not sure what I did or what happened but basically it doesnt operate in shell with decimals
if i type simple
>>> 2/3
0
>>> 3/2
1
if i try to format that through % or format() it doesnt do much either, basically it just doesnt recognize any decimal
>>> a =2/3
>>> a
0
>>> format(a, '.5f')
'0.00000'
I needed a simple division for my code to check something and all of a sudden I encountered something as bizzare as this
I use Python 2.7
In Python 2, / performs "integer division" by default. If you put
from __future__ import division
at the top of your script, it will do the division you want, which will be the default behavior in Python 3. Alternatively, if you want to stay compatible with old Python versions (not recommended for new code), do
2. / 3.
or, with variables
x / float(y)
a = 2/3.
or
a = 2./3
At least one number needs to be a float!
You are performing operations exclusively on integers, which means fractional components of numbers are dropped. You need something like 2.0/3 instead, so floating point arithmetic will be used.