I have the following code:
some_dict = {'a':0, 'b':1}
line = "some_dict_b = %s\n" % pickle.dumps(some_dict,2)
exec(line)
decoded_dict = pickle.loads(some_dict_b)
decoded_dict == some_dict
In python 3 this code prints True. In python 2 (2.7.8) I get an error in the exec line. I know dumps returns str in 2.7 while it returns a byte-stream in 3.
I am writing a program that parses data from an input file then creates certain memory objects and should write out a python script that uses these objects. I write these objects in the script file using pickle.dumps() and inserting it into a variable declaration line as per the idea sketched above. But I need to be able to run this code in python 2.
I did notice that in python 3 the line variable gets each backslash properly escaped and a type:
>>> line
"some_dict_b = b'\\x80\\x02...
while in python 2 I get:
>>> line
'some_dict_b = \x80\x02...
The Python 3 bytes type doesn't have a string represention, so when converted to a string with %s, the object representation is used instead. If you wanted to produce Python-compatible syntax from objects, you can use the %r formatter instead, to just use the representation directly.
In Python 2:
>>> import pickle
>>> some_dict = {'a':0, 'b':1}
>>> p = pickle.dumps(some_dict, 2)
>>> print 'string: %s\nrepresentation: %r' % (p, p)
string: ?}q(UaqKUbqKu.
representation: '\x80\x02}q\x00(U\x01aq\x01K\x00U\x01bq\x02K\x01u.'
In Python 3:
>>> import pickle
>>> some_dict = {'a':0, 'b':1}
>>> p = pickle.dumps(some_dict, 2)
>>> print('string: %s\nrepresentation: %r' % (p, p))
string: b'\x80\x02}q\x00(X\x01\x00\x00\x00bq\x01K\x01X\x01\x00\x00\x00aq\x02K\x00u.'
representation: b'\x80\x02}q\x00(X\x01\x00\x00\x00bq\x01K\x01X\x01\x00\x00\x00aq\x02K\x00u.'
Object representations (the output of the repr() function, which uses the object.__repr__ special method) generally will attempt to provide you with a representation that can be pasted back into a Python script or interactive prompt to recreate the same value.
From the documentation for repr():
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object.
None of this is specific to pickle, really.
Whenever you think "I use exec", think again. You don't. Instead of evaluating data like this, store the contents of the data inside a dict itself.
Then, assign the data explicit to the variable.
some_dict = {'a':0, 'b':1}
line = pickle.dumps(some_dict)
decoded_dict = pickle.loads(line)
decoded_dict == some_dict
You can call repr on the string or bytes object before inserting them into the line.
# Python 2
>>> 'some_dict = %s' % repr(pickle.dumps(d))
'some_dict = "(dp0\\nS\'a\'\\np1\\nI12\\nsS\'b\'\\np2\\nI24\\ns."'
# Python 3
>>> 'some_dict = %s' % repr(pickle.dumps(d))
"some_dict = b'\\x80\\x03}q\\x00(X\\x01\\x00\\x00\\x00bq\\x01K\\x18X\\x01\\x00\\x00\\x00aq\\x02K\\x0cu.'"
Or use the format method, using !r to automatically call repr:
>>> 'some_dict = {!r}'.format(pickle.dumps(d))
"some_dict = b'\\x80\\x03}q\\x00(X\\x01\\x00\\x00\\x00bq\\x01K\\x18X\\x01\\x00\\x00\\x00aq\\x02K\\x0cu.'"
(Also works in python 2)
Related
I am a big fan of using dictionaries to format strings. It helps me read the string format I am using as well as let me take advantage of existing dictionaries. For example:
class MyClass:
def __init__(self):
self.title = 'Title'
a = MyClass()
print 'The title is %(title)s' % a.__dict__
path = '/path/to/a/file'
print 'You put your file here: %(path)s' % locals()
However I cannot figure out the python 3.x syntax for doing the same (or if that is even possible). I would like to do the following
# Fails, KeyError 'latitude'
geopoint = {'latitude':41.123,'longitude':71.091}
print '{latitude} {longitude}'.format(geopoint)
# Succeeds
print '{latitude} {longitude}'.format(latitude=41.123,longitude=71.091)
Is this good for you?
geopoint = {'latitude':41.123,'longitude':71.091}
print('{latitude} {longitude}'.format(**geopoint))
To unpack a dictionary into keyword arguments, use **. Also,, new-style formatting supports referring to attributes of objects and items of mappings:
'{0[latitude]} {0[longitude]}'.format(geopoint)
'The title is {0.title}s'.format(a) # the a from your first example
As Python 3.0 and 3.1 are EOL'ed and no one uses them, you can and should use str.format_map(mapping) (Python 3.2+):
Similar to str.format(**mapping), except that mapping is used directly and not copied to a dict. This is useful if for example mapping is a dict subclass.
What this means is that you can use for example a defaultdict that would set (and return) a default value for keys that are missing:
>>> from collections import defaultdict
>>> vals = defaultdict(lambda: '<unset>', {'bar': 'baz'})
>>> 'foo is {foo} and bar is {bar}'.format_map(vals)
'foo is <unset> and bar is baz'
Even if the mapping provided is a dict, not a subclass, this would probably still be slightly faster.
The difference is not big though, given
>>> d = dict(foo='x', bar='y', baz='z')
then
>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format_map(d)
is about 10 ns (2 %) faster than
>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format(**d)
on my Python 3.4.3. The difference would probably be larger as more keys are in the dictionary, and
Note that the format language is much more flexible than that though; they can contain indexed expressions, attribute accesses and so on, so you can format a whole object, or 2 of them:
>>> p1 = {'latitude':41.123,'longitude':71.091}
>>> p2 = {'latitude':56.456,'longitude':23.456}
>>> '{0[latitude]} {0[longitude]} - {1[latitude]} {1[longitude]}'.format(p1, p2)
'41.123 71.091 - 56.456 23.456'
Starting from 3.6 you can use the interpolated strings too:
>>> f'lat:{p1["latitude"]} lng:{p1["longitude"]}'
'lat:41.123 lng:71.091'
You just need to remember to use the other quote characters within the nested quotes. Another upside of this approach is that it is much faster than calling a formatting method.
print("{latitude} {longitude}".format(**geopoint))
Since the question is specific to Python 3, here's using the new f-string syntax, available since Python 3.6:
>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091
Note the outer single quotes and inner double quotes (you could also do it the other way around).
The Python 2 syntax works in Python 3 as well:
>>> class MyClass:
... def __init__(self):
... self.title = 'Title'
...
>>> a = MyClass()
>>> print('The title is %(title)s' % a.__dict__)
The title is Title
>>>
>>> path = '/path/to/a/file'
>>> print('You put your file here: %(path)s' % locals())
You put your file here: /path/to/a/file
geopoint = {'latitude':41.123,'longitude':71.091}
# working examples.
print(f'{geopoint["latitude"]} {geopoint["longitude"]}') # from above answer
print('{geopoint[latitude]} {geopoint[longitude]}'.format(geopoint=geopoint)) # alternate for format method (including dict name in string).
print('%(latitude)s %(longitude)s'%geopoint) # thanks #tcll
Use format_map to do what you want
print('{latitude} {longitude}'.format_map(geopoint))
This has the advantage that
the dictionary does not have to be blown up into parameters (compared to **geopoint) and that
the format string only has access to the provided map and not the entire scope of variables (compared to F-strings).
Most answers formatted only the values of the dict.
If you want to also format the key into the string you can use dict.items():
geopoint = {'latitude':41.123,'longitude':71.091}
print("{} {}".format(*geopoint.items()))
Output:
('latitude', 41.123) ('longitude', 71.091)
If you want to format in an arbitry way, that is, not showing the key-values like tuples:
from functools import reduce
print("{} is {} and {} is {}".format(*reduce((lambda x, y: x + y), [list(item) for item in geopoint.items()])))
Output:
latitude is 41.123 and longitude is 71.091
I am attempting to read my players health. I have been on a roll but have run into a problem. I am able to read what type of information is at a certain address but can't read what the actual value is, for example here is the response I receive.
<ctypes.c_char_Array_64 object at 0x0000000002EBF9C8>
I am looking for what information is held in the c_char_Array_64 object but have no idea how I would go about it.
Here is my code:
class User:
ctypes.wintypes.DWORD = "Entity"
ctypes.wintypes.c_int = "Team"
ctypes.wintypes.c_int = "Health"
ctypes.wintypes.c_int = "Player"
def getSelfInfo(self):
adr1 = clientdll + dw_LocalPlayer
adr2 = ctypes.create_string_buffer(64)
bytes_read = ctypes.c_size_t()
(rPM(PROCESS.handle, adr1, adr2, sys.getsizeof(ctypes.wintypes.DWORD), ctypes.byref(bytes_read)))
print adr2
t = User()
t.getSelfInfo()
You need to get the value:
print(ar2.value)
From the docs:
If you need mutable memory blocks, ctypes has a create_string_buffer()
function which creates these in various ways. The current memory block
contents can be accessed (or changed) with the raw property; if you
want to access it as NUL terminated string, use the value property:
>>> from ctypes import *
>>> p = create_string_buffer(3) # create a 3 byte buffer, initialized to NUL bytes
>>> print sizeof(p), repr(p.raw)
3 '\x00\x00\x00'
>>> p = create_string_buffer("Hello") # create a buffer containing a NUL terminated string
>>> print sizeof(p), repr(p.raw)
6 'Hello\x00'
>>> print repr(p.value)
'Hello'
>>> p = create_string_buffer("Hello", 10) # create a 10 byte buffer
>>> print sizeof(p), repr(p.raw)
10 'Hello\x00\x00\x00\x00\x00'
>>> p.value = "Hi"
>>> print sizeof(p), repr(p.raw)
10 'Hi\x00lo\x00\x00\x00\x00\x00'
>>>
The empty slice of most ctypes array types will return the Python equivalent type. So to convert your 64 byte buffer to a str (in Py3 bytes), you can do:
print ar2[:]
That will read the full raw 64 bytes mind you. If you want to read it as a C-style string (so the first NUL byte terminates the Python equivalent str), you'd use .value:
print ar2.value
I've got a set filled with value that are present in a JSON, when I print my set I got the following output:
set(['Path\xc3\xa9', 'Synergy Cin\xc3\xa9ma'])
but if I print each element by using a for loop I've got the following output:
Pathé
Synergy Cinéma
Why I don't got the same encoding for each words?
I guess you are using python 2 and it might be related to the default encoding behavior. The value stocked in your set is the "encoded" value and when you use print (which is based on the underlying __repr__ and/or __str__ methods of the object) you get the decoded/formated output (according to the default system encoding).
You can obtain information about the default encoding used with the function sys.getdefaultencoding()
Note that in python 3, encoding is utf-8 by default (ie. by default "any string created (...) is stored as Unicode", according to the documentation) and you wont have the exact same behavior (you can see in the python 2 snippet that the hashed values, as python sets are based on them, are the same if your input string is encoded or not) :
Python 2 :
>>> a = b'Path\xc3\xa9'
>>> a
'Path\xc3\xa9'
>>> print(a)
Pathé
>>> sys.getdefaultencoding()
'ascii'
>>> hash('Pathé')
8776754739882320435
>>> hash(b'Path\xc3\xa9')
8776754739882320435
Python 3:
>>> a = b'Path\xc3\xa9'
>>> a
b'Path\xc3\xa9'
>>> print(a)
b'Path\xc3\xa9'
>>> print(a.decode())
Pathé
>>> sys.getdefaultencoding()
'utf-8'
>>> hash("Pathé")
1530394699459763000
>>> hash(b"Path\xc3\xa9")
1621747577200686773
I am a big fan of using dictionaries to format strings. It helps me read the string format I am using as well as let me take advantage of existing dictionaries. For example:
class MyClass:
def __init__(self):
self.title = 'Title'
a = MyClass()
print 'The title is %(title)s' % a.__dict__
path = '/path/to/a/file'
print 'You put your file here: %(path)s' % locals()
However I cannot figure out the python 3.x syntax for doing the same (or if that is even possible). I would like to do the following
# Fails, KeyError 'latitude'
geopoint = {'latitude':41.123,'longitude':71.091}
print '{latitude} {longitude}'.format(geopoint)
# Succeeds
print '{latitude} {longitude}'.format(latitude=41.123,longitude=71.091)
Is this good for you?
geopoint = {'latitude':41.123,'longitude':71.091}
print('{latitude} {longitude}'.format(**geopoint))
To unpack a dictionary into keyword arguments, use **. Also,, new-style formatting supports referring to attributes of objects and items of mappings:
'{0[latitude]} {0[longitude]}'.format(geopoint)
'The title is {0.title}s'.format(a) # the a from your first example
As Python 3.0 and 3.1 are EOL'ed and no one uses them, you can and should use str.format_map(mapping) (Python 3.2+):
Similar to str.format(**mapping), except that mapping is used directly and not copied to a dict. This is useful if for example mapping is a dict subclass.
What this means is that you can use for example a defaultdict that would set (and return) a default value for keys that are missing:
>>> from collections import defaultdict
>>> vals = defaultdict(lambda: '<unset>', {'bar': 'baz'})
>>> 'foo is {foo} and bar is {bar}'.format_map(vals)
'foo is <unset> and bar is baz'
Even if the mapping provided is a dict, not a subclass, this would probably still be slightly faster.
The difference is not big though, given
>>> d = dict(foo='x', bar='y', baz='z')
then
>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format_map(d)
is about 10 ns (2 %) faster than
>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format(**d)
on my Python 3.4.3. The difference would probably be larger as more keys are in the dictionary, and
Note that the format language is much more flexible than that though; they can contain indexed expressions, attribute accesses and so on, so you can format a whole object, or 2 of them:
>>> p1 = {'latitude':41.123,'longitude':71.091}
>>> p2 = {'latitude':56.456,'longitude':23.456}
>>> '{0[latitude]} {0[longitude]} - {1[latitude]} {1[longitude]}'.format(p1, p2)
'41.123 71.091 - 56.456 23.456'
Starting from 3.6 you can use the interpolated strings too:
>>> f'lat:{p1["latitude"]} lng:{p1["longitude"]}'
'lat:41.123 lng:71.091'
You just need to remember to use the other quote characters within the nested quotes. Another upside of this approach is that it is much faster than calling a formatting method.
print("{latitude} {longitude}".format(**geopoint))
Since the question is specific to Python 3, here's using the new f-string syntax, available since Python 3.6:
>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091
Note the outer single quotes and inner double quotes (you could also do it the other way around).
The Python 2 syntax works in Python 3 as well:
>>> class MyClass:
... def __init__(self):
... self.title = 'Title'
...
>>> a = MyClass()
>>> print('The title is %(title)s' % a.__dict__)
The title is Title
>>>
>>> path = '/path/to/a/file'
>>> print('You put your file here: %(path)s' % locals())
You put your file here: /path/to/a/file
geopoint = {'latitude':41.123,'longitude':71.091}
# working examples.
print(f'{geopoint["latitude"]} {geopoint["longitude"]}') # from above answer
print('{geopoint[latitude]} {geopoint[longitude]}'.format(geopoint=geopoint)) # alternate for format method (including dict name in string).
print('%(latitude)s %(longitude)s'%geopoint) # thanks #tcll
Use format_map to do what you want
print('{latitude} {longitude}'.format_map(geopoint))
This has the advantage that
the dictionary does not have to be blown up into parameters (compared to **geopoint) and that
the format string only has access to the provided map and not the entire scope of variables (compared to F-strings).
Most answers formatted only the values of the dict.
If you want to also format the key into the string you can use dict.items():
geopoint = {'latitude':41.123,'longitude':71.091}
print("{} {}".format(*geopoint.items()))
Output:
('latitude', 41.123) ('longitude', 71.091)
If you want to format in an arbitry way, that is, not showing the key-values like tuples:
from functools import reduce
print("{} is {} and {} is {}".format(*reduce((lambda x, y: x + y), [list(item) for item in geopoint.items()])))
Output:
latitude is 41.123 and longitude is 71.091
How to assign the output of the print function (or any function) to a variable?
To give an example:
import eyeD3
tag = eyeD3.Tag()
tag.link("/some/file.mp3")
print tag.getArtist()
How do I assign the output of print tag.getArtist to a variable?
The print statement in Python converts its arguments to strings, and outputs those strings to stdout. To save the string to a variable instead, only convert it to a string:
a = str(tag.getArtist())
To answer the question more generaly how to redirect standard output to a variable ?
do the following :
from io import StringIO
import sys
result = StringIO()
sys.stdout = result
result_string = result.getvalue()
If you need to do that only in some function do the following :
old_stdout = sys.stdout
# your function containing the previous lines
my_function()
sys.stdout = old_stdout
probably you need one of str,repr or unicode functions
somevar = str(tag.getArtist())
depending which python shell are you using
You can use parameter file to redirect output of print function
from io import StringIO
s = StringIO()
print(42, file=s)
result = s.getvalue()
somevar = tag.getArtist()
http://docs.python.org/tutorial/index.html
This is a standalone example showing how to save the output of a user-written function in Python 3:
from io import StringIO
import sys
def print_audio_tagging_result(value):
print(f"value = {value}")
tag_list = []
for i in range(0,1):
save_stdout = sys.stdout
result = StringIO()
sys.stdout = result
print_audio_tagging_result(i)
sys.stdout = save_stdout
tag_list.append(result.getvalue())
print(tag_list)
Output
['value = 0\n']
In Python 3.x, you can assign print() statement to the variable like this:
>>> var = print('some text')
some text
>>> var
>>> type(var)
<class 'NoneType'>
According to the documentation,
All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.
The file argument must be an object with a write(string) method; if it is not present or None, sys.stdout will be used. Since printed arguments are converted to text strings, print() cannot be used with binary mode file objects. For these, use file.write(...) instead.
That's why we cannot assign print() statement values to the variable. In this question you have ask (or any function). So print() also a function with the return value with None. So the return value of python function is None. But you can call the function(with parenthesis ()) and save the return value in this way.
>>> var = some_function()
So the var variable has the return value of some_function() or the default value None. According to the documentation about print(), All non-keyword arguments are converted to strings like str() does and written to the stream. Lets look what happen inside the str().
Return a string version of object. If object is not provided, returns the empty string. Otherwise, the behavior of str() depends on whether encoding or errors is given, as follows.
So we get a string object, then you can modify the below code line as follows,
>>> var = str(some_function())
or you can use str.join() if you really have a string object.
Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable, including bytes objects. The separator between elements is the string providing this method.
change can be as follows,
>>> var = ''.join(some_function()) # you can use this if some_function() really returns a string value