我想知道如何将用户名转移到另一个文件。但是如果没有整个脚本,我只想导入该变量。
到目前为止,用户必须设置他们希望使用的用户名,然后他们必须为此设置密码。如何导入该用户名变量,但在导入时将输入的数据存储在其中?
用户名代码为:
set_username = input("First enter a username you wish to use: ")
set_password = input("Now enter a password you wish to use: ")
然后,在另一个文件上,用户需要使用他们在另一个文件中设置的用户名和密码登录。我是怎么意思导入用户设置的用户名和密码变量,数据仍然存储在这些变量中。
答案 0 :(得分:1)
您可以在原始文件中创建一个获取/返回用户名和密码的函数。然后,您可以在其他文件中导入此功能。例如,
def get_username():
return set_username
def get_password():
return set_password
然后在你的另一个文件中,你可以说,
from filename import get_username, get_password
答案 1 :(得分:1)
与@agaidis答案类似,您也可以在不使用get函数的情况下导入变量:
from filename import set_username, set_password
答案 2 :(得分:0)
感兴趣并做了一个复杂的例子:定义了一个LoginManager
类来处理使用外部文档列表创建和记录用户的问题。该类应保存在自己的文件中,然后将其导入到创建新用户的代码文件和验证它们的代码文件中(参见代码示例)。
类启动器获取文件的路径作为参数,只要它指向两个代码文件中的相同文件就可以了。
我使用argon2
作为哈希算法,虽然我必须承认我对密码学不熟悉,所以你应该看看我的选择。
import argon2
from pathlib import Path
import re
class LoginManager(object):
"""
Parameters
----------
database : str
File (and path to it) that holds the users and corresponding hashed
passwords.
Examples
--------
Simple `LoginManager`:
>>> temp_database = 'temp_database.txt'
>>> Login1 = LoginManager(temp_database)
>>> Login1.add_user('super_user', 's3kr3tp4ssw0rd')
>>> Login1.login('super_user', 's3kr3tp4ssw0rd')
True
>>> Login1.login('super_user', 't0t411ywr0ng') # wrong password
False
>>> Login1.login('LameUser', 's3kr3tp4ssw0rd') # not existing user
False
New `LoginManager` with the same database:
>>> Login2 = LoginManager(temp_database)
>>> Login2.login('super_user', 's3kr3tp4ssw0rd') # was on Login1
True
>>> Login2.login('super_user', 't0t411ywr0ng') # wrong password
False
>>> Login2.login('LameUser', 't0t411ywr0ng') # not existing user
False
Clean `temp_database` if testing with `doctest`:
>>> import os
>>> os.remove(temp_database)
Notes
-----
* Notice that adding new users to either LoginManager in the example will
not share the new ones between them! Only the users existing at the time
of the creation will be in the LoginManager, so colisions must be must be
avoided by not having two pointing to the same file at the same.
* See more details on `argon2` here:
https://argon2-cffi.readthedocs.io/en/stable/api.html#argon2.PasswordHasher
(also where I saw 's3kr3tp4ssw0rd' and 't0t411ywr0ng')
"""
def __init__(self, database=None):
"""
Create new `LoginManager`.
Notes
-----
Should have better verification whether given path points to a file or
a folder!
"""
if database is None:
database = 'database.txt'
self.database = Path(database)
# create file if it is not there:
if not self.database.is_file():
self.database.touch()
self._reload_database()
self.hasher = argon2.PasswordHasher(time_cost=2,
memory_cost=512,
parallelism=2,
hash_len=16,
salt_len=16,
encoding='utf-8')
self._hash_example = self.hasher.hash('default')
self._max_name_size = 10
def add_user(self, user, password):
"""
Add new user to the `LoginManager` and update `database` file.
Raises `ValueError` if the user already exists or is invalid.
Examples
--------
>>> temp_database = 'temp_database_user.txt'
>>> Login1 = LoginManager(temp_database)
>>> Login1.add_user('super*user', 's3kr3tp4ssw0rd')
Traceback (most recent call last):
ValueError: Invalid characters in user name!
Use only A-Z, a-z, 0-9 and `.`, `-` or `_`.
>>> Login1.add_user('UltraLongUserName', 's3kr3tp4ssw0rd')
Traceback (most recent call last):
ValueError: User name "UltraLongUs..." too long!
Clean `temp_database` if testing with `doctest`:
>>> import os
>>> os.remove(temp_database)
Notes
-----
Does not check users added to the databse file after the `LoginManager`
was created!
"""
self._is_username_valid(user) # raises ValueError if it's not
hashed = self.hasher.hash(password)
self.users[user] = hashed
with self.database.open('ba') as database:
database.write('\t'.join([user.ljust(self._max_name_size),
hashed,
'\r\n']))
# The '\r\n' at the end ensures there's always a new empty line
# after the lattest password, and eases the split of user name and
# password afterwards using '\t' when importing the list.
# The .ljust(self._max_name_size) pads the username with spaces.
# The binary mode is used to ensure future changes are valid (namely
# to allow the use of seek with negative values whithin the file.
def login(self, user, password):
"""
Return `True` if the user/password pair is valid, `False` otherwise.
"""
try:
return self.hasher.verify(self.users.get(user, self._hash_example),
password)
except argon2.exceptions.VerifyMismatchError:
return False
def change_password(self, user, old_password, new_password):
"""
Change password of existing user.
Examples
--------
>>> temp_database = 'temp_database_change_pass.txt'
>>> Login1 = LoginManager(temp_database)
>>> Login1.add_user('super_user', 's3kr3tp4ssw0rd')
>>> Login1.add_user('LameUser', 't0t411ywr0ng')
>>> Login1.add_user('banana', '1234567890')
Test changes to first user:
>>> Login1.login('super_user', 's3kr3tp4ssw0rd')
True
>>> Login1.change_password('super_user',
... 's3kr3tp4ssw0rd',
... 'n3ws3kr3tp4ssw0rd')
>>> Login1.login('super_user', 's3kr3tp4ssw0rd')
False
>>> Login1.login('super_user', 'n3ws3kr3tp4ssw0rd')
True
Test changes to last user:
>>> Login1.change_password('banana',
... '1234567890',
... 'n3ws3kr3tp4ssw0rd')
>>> Login1.login('banana', '1234567890')
False
>>> Login1.login('banana', 'n3ws3kr3tp4ssw0rd')
True
Test changes to a middle user:
>>> Login1.change_password('LameUser',
... 't0t411ywr0ng',
... 'n3ws3kr3tp4ssw0rd')
>>> Login1.login('banana', 't0t411ywr0ng')
False
>>> Login1.login('banana', 'n3ws3kr3tp4ssw0rd')
True
Make sure changes to file are valid:
>>> Login2 = LoginManager(temp_database)
>>> Login2.login('super_user', 'n3ws3kr3tp4ssw0rd')
True
Clean `temp_database` if testing with `doctest`:
>>> import os
>>> os.remove(temp_database)
Notes
-----
If a contact is available to reach the user, it should be used to warn
him of an attempt to change the password.
"""
if self.login(user, old_password):
with self.database.open('br+') as database:
# find user name
line = ' '
while line != '':
line = database.readline()
if line[:self._max_name_size].rstrip() == user:
new_hash = self.hasher.hash(new_password)
database.seek(-len(self._hash_example)-3, 1)
database.write('\t'.join([new_hash, '\r\n']))
self.users[user] = new_hash
break
def _reload_database(self):
self.users = {} # could use a more intuitive name
with self.database.open('r') as database:
lines = database.readlines()
for user_pass in lines:
user, pass_hash, new_line = user_pass.split('\t')
self.users[user.rstrip()] = pass_hash
def _is_username_valid(self, user_name):
"""
Check if user name is valid, raise `ValueError` if it's not.
"""
if user_name in self.users.keys():
raise ValueError('User "%s" already exists!' % (user_name,))
if len(user_name) > self._max_name_size:
raise ValueError('User name "%s..." too long!' %
(user_name[:self._max_name_size+1],))
# From https://stackoverflow.com/questions/1323364/
search = re.compile(r'[^A-Za-z0-9._-]').search
if bool(search(user_name)):
raise ValueError('Invalid characters in user name!\n'
'Use only A-Z, a-z, 0-9 and `.`, `-` or `_`.')
def _test():
"""
Test functions using the doctext examples.
"""
import doctest
doctest.testmod(verbose=False)
if __name__ == "__main__":
# use the examples in documentation to test the code.
_test()
你(和任何人)可以自由地使用和改变,但不要把它作为一个好习惯的例子 - 只是业余人士对这个主题的看法。