2009-08-07 33 views
6

Lỗi phạm vi rất kỳ lạ mà tôi thậm chí không thể nhìn thấy. Bên trong một chức năng cập nhật, tôi có một hàm helper lồng nhau để ... giúp đỡ w/một cái gì đó:pygtk: biến miễn phí được tham chiếu trước khi gán trong phạm vi kèm theo

def attach_row(ws,r1,r2): 
     es = [] 
     for i,w in enumerate(ws): 
      eb = gtk.EventBox() 
      a = gtk.Alignment(xalign=0.0,yalign=0.5) 
      a.add(w) 
      eb.add(a) 
      eb.set_style(self.rowStyle.copy()) 
      es.append(eb)     
      self.table.attach(eb, i, i+1, r1, r2, 
           xoptions=gtk.EXPAND|gtk.FILL, 
           yoptions=gtk.SHRINK) 

     def ene(_,ev): 
      for eb in es: 
       eb.set_state(gtk.STATE_PRELIGHT) 
     def lne(_,ev): 
      for eb in es: 
       eb.set_state(gtk.STATE_NORMAL) 
     for eb in es:     
      eb.connect('enter-notify-event', ene) 
      eb.connect('leave-notify-event', lne) 

này hoạt động một lần trong một thời gian, nhưng nếu bản cập nhật() chức năng chạy quá nhiều, tôi cuối cùng đã nhận được:

for eb in es: 
NameError: free variable 'es' referenced before assignment in enclosing scope 

Điều gì gây ra điều này? es chắc chắn nhất được chỉ định trước khi những chức năng đó được gọi. Đúng không? Là một số điều kỳ lạ xảy ra ở đâu vì một lý do nào đó ene() cho một hàng được tạo trước đó được gọi trong khi hàng mới đang được tạo và đóng trên es bị ghi đè?

Trả lời

4

Khá bí ẩn - có vẻ như việc đóng cửa biến mất khỏi các chức năng bên trong. Tự hỏi nếu đó là liên quan đến cách pygtk giữ chức năng gọi lại như vậy (Tôi không quen thuộc với nội bộ của nó). Để cố gắng tìm hiểu điều đó - điều gì xảy ra nếu bạn cũng nối thêm ene và lne vào danh sách toàn cầu vào cuối attach_row, chỉ để đảm bảo chúng được giữ "bình thường" ở đâu đó để đóng cửa của chúng tồn tại - vấn đề tồn tại trường hợp?

Nếu có, thì tôi phải thừa nhận vấn đề chỉ là bí ẩn và đồng tình với câu trả lời trước đây, như một cách giải quyết, việc sử dụng các cuộc gọi giữ trạng thái của chúng theo một cách rõ ràng hơn. của một thể hiện lớp, vì chúng chia sẻ trạng thái của chúng, nhưng hai cá thể của một lớp đơn với __call__ và nhận trạng thái để thiết lập và danh sách các hộp sự kiện trong số __init__ của nó chắc chắn cũng hợp lý - có hai lớp riêng biệt IMHO sẽ là một chút phóng đại;-).

+0

hehe, true. Tôi thực sự nhận ra rằng tôi có cách làm tốt hơn - thay vì xóa và gắn nhiều hàng, tôi chỉ cần tạo một bộ và thay đổi các vật dụng bên trong chúng. Một lưu ý, mặc dù: Tôi đã thử chuyển "es" làm dữ liệu người dùng cho các hàm ene và lne đó. Điều thú vị là tôi không còn nhận được NameError nữa, nhưng các widget sẽ không nổi bật chút nào. SOmething vẫn đang bị mất ở đâu đó. Nếu điều này xuất hiện trở lại, tôi sẽ thử ý tưởng lớp học. – Claudiu

+0

thậm chí tốt hơn cách - sử dụng một VBox, đặt một hộp sự kiện mỗi hàng, và sau đó sử dụng một nhóm để sắp xếp các cột – Claudiu

+0

yeah điều này đã xảy ra trong các tình huống khác quá. tôi nghĩ là python 2.5 weirdness. vẫn chưa bao giờ tìm thấy câu trả lời – Claudiu

0

Đừng có đủ điểm để rời khỏi đây như một bình luận (chỉ cần đăng ký) ...

  • biến Không 'es' trên toàn cầu hoặc trong một phạm vi cao hơn?
  • attach_row cũng không phải là hàm lồng nhau?
  • TênĐiểm ngoại lệ cho đường vòng lặp trong các hàm ene hoặc lne?

Có thể có một cách khắc phục, có thể là tạo các lớp ene và lne được khởi tạo và gọi là hàm thông qua phương thức __call __().

Các vấn đề liên quan