piglei / one-python-craftsman

来自一位 Pythonista 的编程经验分享,内容涵盖编码技巧、最佳实践与思维模式等方面。

Home Page:https://www.piglei.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2.编写条件分支代码的技巧

leaicc opened this issue · comments

if user.no_profile_exists:
    +++ profile_func = create_user_profile
    extra_args = {'points': 0, 'created': now()}
else:
    +++ profile_func = update_user_profile
    extra_args = {'updated': now()}

profile_func(
    username=user.username,
    email=user.email,
    age=user.age,
    address=user.address,
    **extra_args
)

你好,上面代码中我标记了 “+++” 的两行可以改成下面这样的吗?

create_user_profile = profile_func
update_user_profile = profile_func
if user.no_profile_exists:
    +++ profile_func = create_user_profile
    extra_args = {'points': 0, 'created': now()}
else:
    +++ profile_func = update_user_profile
    extra_args = {'updated': now()}

profile_func(
    username=user.username,
    email=user.email,
    age=user.age,
    address=user.address,
    **extra_args
)

你好,上面代码中我标记了 “+++” 的两行可以改成下面这样的吗?

create_user_profile = profile_func
update_user_profile = profile_func

这样肯定是不行的。在python中函数也是一种对象,它能被赋值给变量,故调用该变量就是执行该函数。感觉你对这个理解有些不清晰,具体可以看廖雪峰的教程开头的例子。作者在这里是巧妙地通过给同一个变量赋予不同的值来执行了不同的函数

感谢帮忙解答,先 close 了 :)

我理解的是:把函数赋值给变量,应该是 变量=函数名,如果是 函数名=变量,而变量之前并没有被定义,那不就报错了吗?

你的理解没有错,只是对代码可能有误解,create_user_profileupdate_user_profile是实际被调用的函数,这里通过条件判断选择需要调用哪个函数,最后使用profile_func来调用选择要调用的函数。

我在 Jupyter 里运行了一下,profile_func = create_user_profile,profile_func = update_user_profilecreate_user_profile = profile_func,update_user_profile = profile_func的结果是一样的,但我还是感觉要写成后者那样,或者说这两种写法有什么不同吗?

扩展了一下原文里的代码,这样可能更容易理解一些。

只有create_user_profileupdate_user_profile是实际实现功能的函数,在条件判断代码里,根据user.no_profile_exists 的值来判断是应该调用create_user_profile还是update_user_profile。此时,profile_func只是指向将要调用的一个函数的变量。

def now():
    return 100

def create_user_profile(username, email, age, address, points, created):
    """ code to create a new user profile """
    print("creating user")

def update_user_profile(username, email, age, address, updated):
    """ code to update a existing user profile """
    print("updating user")

if True:
    profile_func = create_user_profile
    extra_args = {'points': 0, 'created': now()}
else:
    profile_func = update_user_profile
    extra_args = {'updated': now()}

# either create or update a user profile, no matter it already exists or not
profile_func(
    username='user.username',
    email='user.email',
    age='user.age',
    address='user.address',
    **extra_args
)

如果在你标出的位置使用create_user_profile = profile_funcupdate_user_profile = profile_func,此时profile_func根本不能存在,是不可能调到相应的函数的,会报错NameError: name 'profile_func' is not defined

我在Jupyter里面也运行了,的确不会报错,但是也的确没有按照期望调用到相应的函数。原因是Jupyter的执行环境有上下文的,如果你先运行了正确的代码,再执行你的代码,实际上profile_func是在之前的上下文被定义了,所以执行结果一样吧。

贴了我测试的代码,你可以尝试在你想要修改的地方修改再运行试试,注意,我直接用了True/False来控制调用哪个函数,意思差不多。最好别用Jupyter,问题就很明确了。

谢谢,明白了