TypeError-无法将“用户”对象隐式转换为str

时间:2018-06-28 16:12:00

标签: python python-3.x typeerror

我有一个在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

4 个答案:

答案 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页中的信息应有帮助:

在塞巴斯蒂安·拉施卡(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函数之后的以后不需要转换。

因此,这有助于解决这两个错误。

感谢大家的回答和建议,他们提供了很多帮助:)