我试图对PEP8编码风格非常严格,但这个问题还没有为我回答。这是同一代码的两个版本,一个使用临时变量,每个版本只使用一次,另一个版本不使用临时变量,看起来更像函数式语言中常见的变量。
对我来说,功能看起来更漂亮,但我不确定是否有任何关于我应该将多少功能链接在一起的指南。
带有临时变量的版本:
class EmailConfirmation():
@receiver(email_confirmed)
def confirmed(sender, **kwargs):
email = kwargs['email_address'].email
keystone_id = User.objects.get_by_natural_key(email).keystone_id
client = Client(token=settings.KEYSTONE_TOKEN,
endpoint=settings.KEYSTONE_URL)
client.users.update(keystone_id, enabled=True)
不带临时变量的版本:
class EmailConfirmation():
@receiver(email_confirmed)
def confirmed(sender, **kwargs):
Client(
token=settings.KEYSTONE_TOKEN,
endpoint=settings.KEYSTONE_URL
).users.update(
User.objects.get_by_natural_key(
kwargs['email_address'].email
).keystone_id, enabled=True
)
是否有任何指南可以定义推荐这两个版本中的哪个,或者两者都可以?
第一个版本应该是首选。这不仅适用于 Python,也适用于 C++/Java 等其他语言,因为它容易出错,并且根据 Python Errors should never pass silently.
的 Zen,在您的第二个版本中就是这种情况。
原因:
考虑一下,客户端的实例化失败,这会导致返回None
。在不检查成功或正确处理错误的情况下链接同一对象将导致与实际问题AttributeError: 'NoneType' object has no attribute 'users'
无关的错误。
因此,最好避免链接对象,因为这会导致错误静默传递。
例
请考虑对第一个版本进行以下修改
class EmailConfirmation():
@receiver(email_confirmed)
def confirmed(sender, **kwargs):
email = kwargs['email_address'].email
keystone_id = User.objects.get_by_natural_key(email).keystone_id
try:
client = Client(token=settings.KEYSTONE_TOKEN,
endpoint=settings.KEYSTONE_URL)
except CustomClientError as e:
# Your Error Handling Code goes here
raise CustomClientError("Your Error Message")
else:
if client.users:
client.users.update(keystone_id, enabled=True)
else:
raise CustomEmailError("Your Error Message")
finally:
# Cleanup code goes here
PEP8 没有规定是否使用临时变量。
不过,在我看来,第二个版本看起来不是很Pythonic:大多数Python代码都避免像这样的链接方法。我什至可能存储用户而不是keystone_id:
user = User.objects.get_by_natural_key(email)
client = Client(token=settings.KEYSTONE_TOKEN,
endpoint=settings.KEYSTONE_URL)
client.users.update(user.keystone_id, enabled=True)