How to serialize objects using pickle in python3 - python-3.x

I read "How to think like a Computer Scientist. Learning with Python." book. So I usually have no difficulties to interpret examples from python2 to python3, but at chapter 11 Files & Exceptions I encountered this snippet
>>> import pickle
>>> f = open("test.pck", "w")
>>> pickle.dump(12.3, f)
>>> pickle.dump([1,2,3], f)
>>> f.close()
which when I evaluate it using Python 3.5.2 gives this error
Traceback (most recent call last): File "/(myDirs)/files.py", line 3, in <module>
pickle.dump(3.14, f)
TypeError: write() argument must be str, not bytes
I am not a good docs reader, so if you can help me to solve this riddle I would be grateful.

You need to open the file in binary mode.
In line 2:
f = open("test.pck", "wb")

Related

Python Windows path with escape character error

I have a windows path stored in a variable called "a". When I tried to print or use it in the code, somehow some special characters are added to the string.
>>> import re
>>> from pathlib import Path
>>>
>>>
>>> a = "E:\POC\testing\functionalities\logs\timer.logs"
>>> a
'E:\\POC\testing\x0cunctionalities\\logs\timer.logs'
>>>
>>> Path(a)
WindowsPath('E:/POC\testing\x0cunctionalities/logs\timer.logs')
>>> Path.absolute(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\program files (x86)\python38-32\lib\pathlib.py", line 1159, in absolute
if self._closed:
AttributeError: 'str' object has no attribute '_closed'
>>>
>>> re.escape(a)
'E:\\\\POC\\\testing\\\x0cunctionalities\\\\logs\\\timer\\.logs'
>>>
>>> a.replace("\\", "/")
'E:/POC\testing\x0cunctionalities/logs\timer.logs'
>>> a.__repr__()
"'E:\\\\POC\\testing\\x0cunctionalities\\\\logs\\timer.logs'"
>>>
I'm able to handle all the special characters but \f is somehow changed to \x0c.
One solution is adding r to the string, but my path is stored in a variable. How I can achieve that? I'm using python 3.8.5 and Windows 10
>>> a = r"E:\POC\testing\functionalities\logs\timer.logs"
>>> a
'E:\\POC\\testing\\functionalities\\logs\\timer.logs'
>>>
>>>
>>> a = "E:\POC\testing\functionalities\logs\timer.logs"
>>> a = r"" + a
>>> a
'E:\\POC\testing\x0cunctionalities\\logs\timer.logs'
>>>
Use raw string or escape the backward slash:
a = r"E:\POC\testing\functionalities\logs\timer.logs"
or
a = "E:\\POC\\testing\\functionalities\\logs\\timer.logs"
Based on your comment under #user8086906's post, couldn't you just do
a.replace('\\', '\')
? I see you tried a.replace("\\", "/") above - could you explain what the desired behavior is? On my machine, the first snippet I posted works.
EDIT:
Thanks #Gopirengaraj C - I see what the issue is now. The problem is that \f is an escape character in Unicode - more specifically, it is called a "form feed". I think a good way to get around this would then be to avoid replace and do something like this instead:
a = r'{0}'.format(a)
Lmk if that works.

Simple function won't run, beginner coder at work

I'm learning Python and it's early days for me. The following small bit of code won't run, the error message is
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'logdata' is not defined
The file is called "logdata.py". The faulty(?) code is;
def logthis(addme):
f=open("log.txt", "a+")
f.write(addme)
f.close()
logthis('teststring')
If there is a better place for a basic question like this please let me know, I'm sure i'll have plenty more to come as i learn Python, thanks!
I think, you have some extra lines of code in beginning of file which uses undefined identifier (variable, function etc.) with name logdata. Something like this.
>>> def f():
... print(logdata)
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
NameError: name 'logdata' is not defined
>>>
If so, just define/initialize that. Finally, your code will work fine then as I have already tested it as follows.
>>> def logthis(addme):
... f = open("log.txt", "a+")
... f.write(addme)
... f.close()
...
>>> logthis('teststring')
>>>
>>> # Read the newly created file content
...
>>> f = open("log.txt", "r")
>>> f.read()
'teststring'
>>>

Python3 reading Japanese characters in a pickle file made in python2

I use the code below to read a pickle file made in python2
import pickle
with open('data.pkl', 'rb') as fin:
data_df = pickle.load(fin, encoding='latin1')
Everything works well except the column including Japanese charactors.
For example, string supposed to be "東京都" may become something like "æ±äº¬é".
I think python3 reads the bytes format string as str. How can I convert it back?
Here is some test I did in python3
>>> a='\xe6\x9d\xb1\xe4\xba\xac\xe9\x83\xbd'
>>> b=b'\xe6\x9d\xb1\xe4\xba\xac\xe9\x83\xbd'
>>> a
'æ\x9d±äº¬é\x83½'
>>> b
b'\xe6\x9d\xb1\xe4\xba\xac\xe9\x83\xbd'
>>> print(a)
æ±äº¬é
>>> print(b)
b'\xe6\x9d\xb1\xe4\xba\xac\xe9\x83\xbd'
>>> a.decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'
>>> b.decode('utf-8')
'東京都'
I think pickle.load reads the utf-8 code as str (like the a case above).
[EDIT]
The reason why I set pickle.load encoding to latin1 was because there's column with datetime format. It causes error if I set encoding='utf-8

%s error when trying to put a variable into a string python

Trying to build a "launcher" type thing for youtube-dl(program that lets you download youtube videos), and getting an error. I understand what the error means but it makes no sense as I am(I think) doing exactly what python wants.
This is my code:
import os
import sys
x = input('Enter link for youtube Video you would like to download: ')
ytdp = open('C:\\Games\\ytdp.bat', 'w')
ytdp.write('cd C:\\Users\Jake\Music')
ytdp.write('\n')
ytdp.write('youtube-dl %s')% (x)
ytdp.close()
os.startfile('C:\\Games\ytdp.bat')
sys.exit()
This is the error I get when running the code
Traceback (most recent call last):
File "C:\Users\Jake\Desktop\Youtube video downloader.py", line 8, in <module>
ytdp.write('youtube-dl %s')% (xx)
TypeError: unsupported operand type(s) for %: 'int' and 'str'
ytdp.write('youtube-dl %s')% (xx)
Should be
ytdp.write('youtube-dl %s'% (xx))
Here is some more info on it

QTreeWidgetItem not hashable in python3

I need to port some python2 code to python3.
There I found that a dict of QTreeWidgetItem is created. In Python 2 this is working fine, as the object is hashable. But in python 3 you will get an error because __hash__ is not implemented:
$ python2
>>> from PyQt5 import QtWidgets
>>> x = QtWidgets.QTreeWidgetItem()
>>> foo = {x: 23}
>>> hash(x)
-9223363252877437056
$ python3
>>> from PyQt5 import QtWidgets
>>> x = QtWidgets.QTreeWidgetItem()
>>> hash(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'QTreeWidgetItem'
I consider this is a bug or is there any reason for this, that I do not see?
The PyQt5 documentation does not mention anything in this direction, and for QTreeWidgetItem, there is only the C++ doc available, which does not help in this python specific case.

Resources