2012-08-02 50 views
0

我在訪問類實例時遇到了一些問題。我從一個過程調用類,實例的名稱是在一些變量中定義的。我想要創建實例名稱的值,然後想要訪問它,但是當我訪問它是給錯誤。有人可以幫助解決這個問題。訪問python中的類對象時出錯

class myclass: 
    def __init__(self,object): 
    self.name = object 

def mydef(): 
    global a1 
    b = "a1" 
    b = myclass(b) 

mydef() 
print a1.name 

問題二: 在我實際的劇本,我必須從這個函數(約100),創造了大量這樣的實例。因此,將其名稱定義爲全局名稱會很痛苦,有沒有辦法在函數外部訪問這些實例,而無需將它們聲明爲全局的。

修改:

class myclass: 
    def __init__(self,object,typename): 
     self.name = object 
     self.typeid = typename 

def mydef(): 
    file_han = open(file,"r") 
    while True: 
     line = file_han.readline() 
     if not line: 
     break 
     start = line.find('"') 
     end = line.find('"',start+1) 
     string_f = line[start+1:end] 
     myclass(string_f,'a11')   

mydef(file) 

print def.name 
print def.typeid 

File Contents are : 
a11 "def" 
a11 "ghi" 
a11 "eff" 
+0

你需要修復您的壓痕;例如,它在* mydef()'應該聲明的級別上*不清楚。有關格式化的幫助,請參見[如何格式化我的代碼塊?](http://meta.stackexchange.com/q/22186) – 2012-08-02 10:33:54

+0

mydef和類聲明處於同一級別。 – sarbjit 2012-08-02 10:38:44

+0

我把這個問題推回去了。在接受的答案中有一些缺失的上下文(沒有看到你使用'globals'保存修訂歷史的地方)。 – Makoto 2012-08-02 13:02:36

回答

3

以下是我想做到這一點。我不知道你爲什麼要弄亂全局變量,如果你願意解釋,我會更新我的答案。

class Myclass(object): 
    def __init__(self, name): 
     self.name = name 

def mydef(): 
    return Myclass("a1") 

a1 = mydef() 
print a1.name 

收集您的實例在列表中:

instances = [] 
for x in range(1000): 
    instances.append(Myclass("Instance {0}".format(x))) 
print instance[42].name 

注意的變化:

  • 類名應該大寫
  • 使用object作爲基類的類(自python 2.2,但在3.x中不再需要)
  • 不要shad流內置object與參數名
  • ,只用字符串"a1"直接作爲參數,而不是將其分配給從函數的變量
  • 返回的東西,而不是通過全局變量傳遞結果

RE:評論

你還沒有說有關這些文件格式的任何信息,所以我只給其中要讀取的文件中包含每行一個類名的例子,沒有別的:

def mydef(filename): 
    ret = [] 
    with open(filename) as f: 
     for line in f: 
      # Call `strip` on line to remove newline and surrounding whitespace 
      ret.append(Myclass(line.strip())) 
    return ret 

所以,如果你有幾個文件,並希望所有的情況下,從您的所有文件添加到大名單,像這樣做:

instances = [] 
for filename in ["myfile1", "myfile2", "myfile3"]: 
    instances.extend(mydef(filename)) 

RE:OP編輯

def mydef(filename): 
    ret = [] 
    with open(filename, "r") as file_han: 
     for line in file_han: 
      string_f = line.split('"')[1] 
      ret.append(Myclass(string_f)) 
    return ret 

i = mydef("name_of_file") 

RE:評論

哦,你想通過名字訪問它們。雙方行號和姓名索引 - 評

如果我理解正確的話,你想兩者兼得:然後返回dict代替:

def mydef(filename): 
    ret = {} 
    with open(filename, "r") as file_han: 
     for line in file_han: 
      string_f = line.split('"')[1] 
      ret[string_f] = Myclass(string_f) 
    return ret 

i = mydef("name_of_file") 
print i["ghi"].name # should print "ghi" 

RE。那麼爲什麼你不返回一個列表和一個字典?

def mydef(filename): 
    d = {} 
    L = [] 
    with open(filename, "r") as file_han: 
     for line in file_han: 
      string_f = line.split('"')[1] 
      instance = Myclass(string_f) 
      d[string_f] = instance 
      L.append(instance) 
    return L, d 

L, d = mydef("name_of_file") 
print d["ghi"].name 
print L[3] 
print L.index(d["ghi"]) 
+0

實際上,在我原來的腳本中,mydef對應的是一個函數,當被調用的時候會打開一個文件,並且根據文件的內容,會根據從文件中讀取的值創建實例名稱。此外,我將有多個類需要在該功能內部調用(取決於文件中的一些關鍵字)。所以我不能像你使用的那樣使用return語句,因爲我需要從文件中定義的文本中提取實例名稱。 – sarbjit 2012-08-02 10:49:35

+0

thx爲您提供幫助,請參閱我的修改後的代碼,因爲您可以看到我必須在調用類定義之前將從文件中提取的值存儲在另一個變量中。 – sarbjit 2012-08-02 11:14:21

+0

@sarbjit這樣做沒有問題,只是在您首次展示的代碼中沒有必要。只需修改您的代碼即可返回實例列表,而且您可以輕鬆前往。 – 2012-08-02 11:25:14

0

你可以使用類作爲庫用於實例,例如

class Named(object): 
    def __init__(self,name): 
     self.name = name 

    def __new__(cls,name): 
     instance = super(type,cls).__new__(cls,name) 
     setattr(cls,name,instance) 
     return instance 

    def __repr__(self): 
     return 'Named[%s]'%self.name 

Named('hello') 
Named('x123') 
Named('this is not valid attribute name, but also working') 

print(Named.hello,Named.x123,getattr(Named,'this is not valid attribute name, but also working'))