Python函数的最佳实践

时间:2015-05-29 13:42:43

标签: python

方法1(全局变量):

id_constant = 1000
id_cnt = 1
def give_id():
    global id_cnt
    id_cnt += 1
    return id_constant * id_cnt
id = give_id()

方法2(fuc var而不是global var):

id_cnt = 1
def give_id():
    id_constant = 1000
    global id_cnt
    id_cnt += 1
    return id_constant * id_cnt
id = give_id()

方法3(通过全球大战):

id_cnt = 1
id_constant = 1000
def give_id(constant, cnt):
    return constant * cnt
global id_cnt
id_cnt +=1
id = give_id(id_constant, id_cnt)

我不确定是否有任何一般的经验法则但是广泛接受函数来访问函数内的全局变量?或者如果变量仅用于函数,那么它应该是函数变量的一部分吗?

6 个答案:

答案 0 :(得分:4)

该方法通常取决于具体情况。

您似乎需要独特的ID,为什么不使用生成器

def create_id_generator():
    """Returns an id generator."""
    i = 0
    while True:
        yield i
        i += 1

next()功能一起使用:

>>> ID_GENERATOR = create_id_generator()  # Global variable
>>> my_id = next(ID_GENERATOR)
>>> my_id2 = next(ID_GENERATOR)
>>> my_id3 = next(ID_GENERATOR)
>>> print(my_id, my_id2, my_id3, next(ID_GENERATOR))
0 1 2 3

如果您希望id为1000的倍数,则可以通过参数将常量传递给生成器:

def create_id_generator(multiplier=1000):
    """Returns an id generator."""
    i = 0
    while True:
        yield i * multiplier
        i += 1

如果您不想从索引0开始,您甚至可以添加起始值:

def create_id_generator(multiplier=1000, start_index=0):
    """Returns an id generator."""
    while True:
        yield start_index * multiplier
        start_index += 1

答案 1 :(得分:3)

如果id_constant 实际上是常数,我会做的:

ID_CONSTANT = 1000

def give_id(id_count):
    return ID_CONSTANT * id_count

id_count = 1

id = give_id(id_count)

但看起来你也有一些状态(id_count)需要与id的发布保持同步,建议生成器功能:

def give_id(id_count):
    while True:
        yield ID_CONSTANT * id_count
        id_count += 1

甚至是一个班级:

class IdCreator(object):

    ID_CONSTANT = 1000

    def __init__(self, start_count=1):
        self.id_count = start_count

    def give_id(self):
        new_id = self.ID_CONSTANT * self.id_count
        self.id_count += 1
        return new_id

你可以更进一步,implement iteration为班级。

答案 2 :(得分:2)

来自Python的禅宗(即import this

Namespaces are one honking great idea -- let's do more of those!

通常,如果你不需要在全局命名空间中放置一些东西,最好将它封装在函数的本地命名空间中,所以我认为选项2更加“pythonic”,除非{{1将被多个函数使用。

您也可以使用带有默认值的关键字参数尝试以下操作:

id_constant

然后,如果您需要将id_constant变为不同的东西,则可以将该函数称为id = give_id(id_constant = 500)。

答案 3 :(得分:2)

全局变量通常是你应该避免的。

如果你想拥有常量,让我们说,配置目的,我会采取更多的模块方法,如:

conf.py

 MYCONST = 1000

app.py

import conf

print conf.MYCONST

或采取OO方法,例如:

class Test(object):

    def __init__(self):
        self._constant = 1000

    def give_id(self, cnt):
        return self._constant * cnt

答案 4 :(得分:1)

你可能需要发电机功能吗?

def give_id(id_constant):
    delta = 0
    while True:
        delta += 1
        yield id_constant + delta

for i in range(100):
    print(give_id(1000))  # prints numbers from 1001 to 1100

答案 5 :(得分:1)

一些棘手的东西:

def get_id_func(constant):
    class c(object):
        def __init__(self, constant):
            self.constant = constant
            self.id = 0
        def func(self):
            self.id += 1
            return self.id * self.constant
    o = c(constant)
    return o.func

# create function
f = get_id_func(1000)

# call and test it
assert f() == 1000
assert f() == 2000
assert f() == 3000