2010-10-15 39 views
7

Có thể khai báo các hàm trong python và xác định chúng sau này hoặc trong một tệp riêng biệt không?Khai báo hàm trong python để có mã có thể đọc và sạch?

Tôi có một số mã như:

class tata: 
    def method1(self): 
     def func1(): 
     # This local function will be only used in method1, so there is no use to 
     # define it outside. 
     # Some code for func1. 
     # Some code for method1. 

Vấn đề là mã trở nên lộn xộn và khó đọc. Vì vậy, tôi tự hỏi nếu nó có thể ví dụ để tuyên bố func1 bên trong method1 và xác định nó sau này?

+0

Nếu hàm func1() thực sự chỉ liên quan đến phương thức 1(), và phương thức bên trong trở thành một vấn đề với bạn, đó là dấu hiệu cho thấy nó thực sự là một lớp riêng biệt. –

Trả lời

6

Chắc chắn, không có vấn đề:

foo.py:

def func1(): 
    pass 

script.py:

import foo 
class tata: 
    def method1(self): 
     func1=foo.func1 
+0

Tư duy tuyệt vời! Tuy nhiên ý tưởng của một hàm cục bộ là làm cho hàm này chỉ sử dụng được bên trong phạm vi bên trong. Vì vậy, điểm của việc xác định 'func1' mới bên trong' method1' là gì? Sẽ không dễ dàng hơn khi thực hiện: 'từ foo import func1' và sử dụng nó. – banx

+0

@banx: Câu trả lời của Alex Martelli ở đây (http: // stackoverflow.com/questions/1744258/is-import-module-better-coding-style-hơn-from-module-import-function) đã thuyết phục tôi tránh 'từ foo import func1' hoàn toàn. – unutbu

+0

@banx: Có, đặt định nghĩa của 'func1' bên trong' method1' làm cho nó ít nhất là bán riêng tư, mặc dù tôi sẽ không đặt nó qua một hacker bytecode enterprising (http://stackoverflow.com/questions/3908335/python -function-local-name-binding-from-an-outer-scope/3913185 # 3913185) để tìm một cách để làm cho những gì bạn nghĩ là riêng tư không phải là quá riêng tư. – unutbu

2

Định nghĩa bên trong tạo tên riêng trong phạm vi bên trong. Nó sẽ đổ bóng bất cứ điều gì bạn xác định sau này với cùng một tên. Nếu bạn muốn xác định hàm này sau đó, thì chỉ cần làm như vậy. Tên sẽ chỉ được kiểm tra khi nó thực sự được sử dụng.

def foo(): 
    print 'foo' 
    bar() 

def bar(): 
    print 'bar' 

foo() 
3

Tôi nghĩ rằng những gì bạn muốn là để nhập khẩu các chức năng trong method1 , ví dụ

def method1(...): 
    from module_where_func1_is_defined import func1 
    # do stuff 
    something = func1(stuff, more_stuff) 
    # do more stuff 

Mô-đun Python về cơ bản chỉ là các tệp; miễn là tệp module_where_func1_is_defined.py nằm trong cùng thư mục với tập lệnh của bạn, method1 sẽ có thể nhập tệp.

Nếu bạn muốn để có thể tùy chỉnh cách method1 công trình, và cũng có thể làm cho nó thậm chí nhiều hơn rõ ràng rằng nó sử dụng func1, bạn có thể vượt qua func1-method1 như một tham số mặc định:

import other_module 

# various codes 

def method1(other_args, func=other_module.func1) 
    # do stuff 
    something = func(stuff, more_stuff) 
    # do more stuff 
2

Nếu Func1 () cần xử lý bất cứ điều gì có trong phạm vi của method1() bạn tốt nhất để lại định nghĩa của func1() ở đó. Bạn sẽ cần phải có Func1() nhận được bất kỳ dữ liệu thích hợp như các thông số nếu nó không được định nghĩa trong phạm vi method1()

+0

+1 Vì có các hàm lồng nhau truy cập trực tiếp tên từ phạm vi chứa của chúng là một thành ngữ quan trọng trong Python. Các quy tắc phạm vi hiện tại rất mạnh mẽ và được suy nghĩ cẩn thận - xem [PEP 227 - Phạm vi lồng nhau tĩnh (ttp: //www.python.org/dev/peps/pep-0227/) được giới thiệu trong Python 2.1. Đặt định nghĩa trong một tệp riêng biệt hiện tại sẽ ngăn chặn điều này trừ khi làm việc xung quanh bằng cách nào đó. – martineau

0

Bạn có thể tạo các phương pháp sau

 

class Something(object): 
    def test1(self): 
    pass 

def dummy(self): 
    print "ok", self 

Something.test1 = dummy 

Tuy nhiên nó không thể có một ẩn danh chức năng (tốt, có biểu thức lambda nhưng bạn không thể có báo cáo có), do đó bạn phải cung cấp một tên tạm thời

bạn có thể muốn sử dụng trang trí để làm cho nó dễ đọc hơn:

 
def define(cls, name): 
    def decor(f): 
    setattr(cls, name, f) 
    return decor 


class Something(object): 
    def test1(self): 
    pass 

@define(Something, "test1") 
def dummy(self): 
    print "ok", self 

Mã này phải dễ đọc hơn. Nó vẫn sẽ gây ô nhiễm dummy nhưng khởi tạo nó với null.

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