2015-05-29 83 views
3

方法1(全局變量):爲函數的Python最佳實踐

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變種而不是全局變量):

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) 

即時通訊不確定是否有任何一般的經驗法則,但是被廣泛接受的函數來訪問一個函數內的全局變量重刑?或者如果變量只用於一個函數,那麼它應該是一個函數變量的一部分嗎?

+2

有時是必要的,但總的來說,在所有的語言,訪問'global'變量是不好的做法 – Scironic

+1

一般較少的全局變量意味着更好的代碼,所以嘗試使用參數並返回值而不是全局變量。什麼來問你的問題,上下文將有助於爲你選擇最好的方法。你在用什麼ID? –

+0

不要忘記你可以在函數參數中使用默認值,例如:'def foo(bar = 4):\ print bar',如果調用爲'foo()',將會打印'4'。通常這對於很少更改的配置變量來說更好,因爲它避免了全局變量(實際上是模塊級別的變量),並且保持常量接近代碼中的使用。 – thirtythreeforty

回答

4

該方法通常取決於情況。

你似乎需要唯一的ID,爲什麼不使用發電機

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

使用的next()功能:如果你想要的ID是的1000倍數

>>> 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 

,您可以通過參數將常數傳遞給發電機:

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 
2

通過Python的禪(即import this

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

一般來說,如果你不需要把東西在全局命名空間,最好是將其封裝在函數的局部命名空間,所以我會認爲選項2會更「pythonic」,除非id_constant將被多個函數使用。

您也可以嘗試以下使用關鍵字參數有一個默認值:

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

然後,如果你曾經需要id_constant是不同的東西,你可以調用函數爲ID = give_id(id_constant = 500 )。

+1

在當前版本中,函數參數被忽略。 – kratenko

+0

哎呀!謝謝你的收穫 –

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

全局變量通常是您應該避免的。

如果你想擁有常數,對我們說,配置目的,我會採取更象一個模塊的方法:

conf.py

MYCONST = 1000 

app.py

import conf 

print conf.MYCONST 

或採取面向對象方法,如:

class Test(object): 

    def __init__(self): 
     self._constant = 1000 

    def give_id(self, cnt): 
     return self._constant * cnt 
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 
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