我有一个在python 2.7上运行良好的代码,但是后来我迁移到了python 3.5,它不再运行了,我遇到了一个错误。 这是代码:
def gen_cert(keyname, certname, password, username):
cmd = [
'openssl', 'pkcs12', '-name', username, '-inkey', tempdirname + keyname,
'-in', tempdirname + certname, '-export', '-out',
dirname + username + '.p12', '-password', 'pass:' + password
]
s = subprocess.Popen(cmd, shell=False)
out, err = s.communicate('\n'.encode())
错误是-Can't convert 'User' object to str implicitly
此dirname + username + '.p12'
以下是局部变量:
| Variable | Value |
______________________________
| certname |'w0ui8t9mkg.pem' |
| keyname |'7g89utc1it.pem' |
| password |'bo02qm99ui' |
| username |<User: abcuser>|
这里是调用上面函数的函数:
def generate_user_certificate(self, request, queryset):
check_folders(request)
UsersList = []
for qs in queryset:
username = qs.username
keyname = random_name('.pem')
certname = random_name('.pem')
password = random_name('')
gen_cert(keyname, certname, password, username)
UsersList.append(username)
# Displaying success message for certificate generation
allusers = ', '.join(UsersList)
messages.success(
request,
"Certificates for users: " + allusers + " generated successfully.")
我在allusers = ', '.join(UsersList)
中也遇到了错误
上面写着sequence item 0: expected str instance, User found
如何解决? 我正在使用django 2.0
答案 0 :(得分:2)
简要建议:
发生的情况是qs.username
指向一个User
对象,但是您希望它指向一个字符串(即该User
对象的用户名)。除了以下修复之外,我建议您尝试更改queryset中的键。现在,您拥有键username
指向一个非用户名的键,这很令人困惑(尽管您无需执行此操作即可使代码正常工作;这只是一种样式建议)。>
如何解决错误:
假设您使用默认的Django.contrib.auth用户模型,则可以使用User.get_username()
访问用户名。我之前推荐的str(username)
方法也可以使用,因为它调用__str__()
对象上的User
函数,该函数默认返回用户名。最好在调用gen_cert()
时通过设置username
变量来调用这两种方法:
username = qs.username.get_username()
或
username = str(qs.username)
对于第二个关于allusers = ', '.join(UsersList)
的问题,我想您也遇到了同样的问题,一旦username
变量实际上指向一个字符串而不是一个{{1} }对象。
答案 1 :(得分:2)
您正在尝试连接两个对象,但是其中至少一个对象不是str类型的,为此,您应该实现User类的__str__
方法,在该方法中返回代表您的类的值这样您就可以按自己希望的方式dirname + str(username)
调用username.__str__
方法
答案 2 :(得分:0)
这看起来像是数据类型错误或问题。您视为String类型的项目实际上存储为Object类型。找出数据类型,然后适当地处理它。您需要转换类型。将您的用户名转换为字符串,然后再将其读入代码中的cmd行
我认为这行代码需要更改: cmd = ['某些内容在这里,目录名+用户名+'.p12']
class str(object='')
class str(object=b'', encoding='utf-8', errors='strict')
返回对象的字符串版本。如果未提供object,则返回空字符串。否则,str()的行为取决于是否给出编码或错误,如下所示。
如果既未给出编码也未给出错误,则str(object)返回object。 str (),它是object的“非正式”或可打印的字符串表示形式。对于字符串对象,这是字符串本身。如果object没有 str ()方法,则str()会返回返回repr(object)。
如果至少给出了编码或错误之一,则object应该是类似字节的对象(例如bytes或bytearray)。在这种情况下,如果object是字节(或bytearray)对象,则str(bytes,encoding,errors)等效于bytes.decode(encoding,errors)。否则,将在调用bytes.decode()之前获取缓冲区对象基础的bytes对象。有关缓冲区对象的信息,请参见二进制序列类型-字节,字节数组,内存视图和缓冲区协议。
在没有编码或错误参数的情况下将字节对象传递给str()属于返回非正式字符串表示形式的第一种情况(另请参见Python的-b命令行选项)。例如:
str(b'Zoot!')
"b'Zoot!'"
有关str类及其方法的更多信息,请参见文本序列类型— str和下面的“字符串方法”部分。要输出格式化的字符串,请参阅格式化的字符串文字和格式化字符串语法部分。此外,请参阅“文本处理服务”部分。
str.format(* args,** kwargs)
执行字符串格式化操作。调用此方法的字符串可以包含文字文本或用大括号{}分隔的替换字段。每个替换字段都包含位置参数的数字索引或关键字参数的名称。返回字符串的副本,其中每个替换字段都用相应参数的字符串值替换。
"The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'
以下3页中的信息应有帮助:
Python3 Error: TypeError: Can't convert 'bytes' object to str implicitly
http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html
https://geeksforgeeks.org/important-differences-between-python-2-x-and-python-3-x-with-examples/
在塞巴斯蒂安·拉施卡(Sebastian Raschka)的站点上:
Unicode Python 2具有ASCII str()类型,单独的unicode(),但没有字节类型。 (在您的情况下,以前用作字符串的内容现在被视为对象。)
Python 3,具有Unicode(utf-8)字符串和2个字节的类:字节和字节数组。
Python 2:
In: print 'they are really' + b' the same'
Out: they are really the same
Python 3:
IN: print('and Python', python_version(), end="")
IN: print(' also has', type(bytearray(b'bytearrays')))
OUT: and Python 3.4.1 also has <class 'bytearray'>
'note that we cannot add a string' + b'bytes for data'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-d3e8942ccf81> in <module>()
----> 1 'note that we cannot add a string' + b'bytes for data'
TypeError: Can't convert 'bytes' object to str implicitly
来自geeksforgeeks:
Unicode:
在Python 2中,隐式str类型为ASCII。但是在Python 3.x中,隐式str类型是Unicode。
print(type('default string '))
print(type(b'string with b '))
'''
Output in Python 2.x (Bytes is same as str)
<type 'str'>
<type 'str'>
Output in Python 3.x (Bytes and str are different)
<class 'str'>
<class 'bytes'>
'''
答案 3 :(得分:0)
更改此错误均可以解决:
for qs in queryset:
username = qs.username
对此:
for qs in queryset:
username = str(qs.username)
不是使用username = qs.username
而是使用username = str(qs.username)
,这会将username
转换为str
,因此在调用gen_cert
函数之后的以后不需要转换。
因此,这有助于解决这两个错误。
感谢大家的回答和建议,他们提供了很多帮助:)