2008-10-10 15 views
184
dir(re.compile(pattern)) 

không trả về mẫu làm một trong các thành phần của danh sách. Cụ thể là nó sẽ trả về:Làm thế nào để có được một danh sách đầy đủ các phương pháp và các thuộc tính của đối tượng?

['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn'] 

Theo hướng dẫn, nó là vụ phải chứa

the object's attributes' names, the names of its class's attributes, and recursively of the attributes of its class's base classes.

Nó cũng nói rằng

The list is not necessarily complete.

Có cách nào để có được hoàn chỉnh danh sách ? Tôi luôn luôn giả định rằng dir trả về một danh sách đầy đủ nhưng dường như nó không ...

Ngoài ra: có cách nào để chỉ liệt kê các thuộc tính không? Hoặc chỉ có phương pháp?

Edit: đây thực sự là một lỗi trong python -> cho là nó được cố định tại các chi nhánh 3.0 (và có lẽ cũng trong 2,6)

+4

sử dụng 'dir()' hoặc mô-đun kiểm tra thường là cách phù hợp để thực hiện. Bạn có sử dụng mô đun 're' làm ví dụ hay bạn muốn đạt được mục tiêu đặc biệt? – hop

+1

Bạn có chắc chắn rằng mẫu này thực sự được lưu giữ dưới dạng dữ liệu khi được biên dịch không? Tôi đã ấn tượng rằng điểm biên dịch một mẫu là tạo ra các automata trạng thái hữu hạn cần thiết để phân tích mẫu đã cho. –

+0

@hop không thể dir được sidestepped bởi các lớp học? Ví dụ, họ có thể thực hiện trên '__dir __()' – ytpillai

Trả lời

118

Đối với hoàn danh sách các thuộc tính, câu trả lời ngắn gọn là: Không. Vấn đề là các thuộc tính thực sự được định nghĩa là các đối số được chấp nhận bởi hàm tích hợp getattr. Khi người dùng có thể thực hiện lại __getattr__, đột nhiên cho phép bất kỳ loại thuộc tính nào, không có cách nào có thể chung để tạo danh sách đó. Hàm dir trả về các khóa trong thuộc tính __dict__, tức là tất cả các thuộc tính có thể truy cập được nếu phương pháp __getattr__ không được thực hiện lại.

Đối với câu hỏi thứ hai, điều đó không thực sự hợp lý. Trên thực tế, các phương thức là các thuộc tính có thể gọi được, không có gì hơn. Bạn có thể lọc các thuộc tính có thể gọi và sử dụng mô-đun inspect để xác định các phương thức, phương thức hoặc hàm của lớp.

+0

inpect.getmembers (lại. biên dịch (mô hình)) không mang lại mô hình như một thành viên hoặc là, vì vậy nó có thể sử dụng dir nội bộ ... Điều này sucks! –

+0

Tôi cũng có thể sử dụng có thể gọi để kiểm tra xem chúng có phải là phương pháp hay không, nhưng đó không phải là điểm ... Vấn đề là tôi không thể tin tưởng dir để trả về ngay cả danh sách các thuộc tính thực sự được hiển thị công khai ... –

+2

kiểm tra có nghĩa là "ít nhất là" đáng tin cậy như dir(). mặt khác, lại là một mô-đun rất phức tạp – hop

48

Đó là lý do tại sao các phương pháp mới __dir__() đã được thêm vào trong python 2,6

see:

+0

tôi nhận được lỗi này: >> __dir __ (pyrenderdoc) Traceback (gần đây nhất gọi cuối cùng): File "", dòng 1, trong NameError: Tên '__dir__' không được định nghĩa –

+0

'__dir' __ () là một phương pháp trên đối tượng, không phải là một chức năng - vui lòng đọc các liên kết trong câu trả lời và [this] (https://docs.python.org/3/reference/datamodel.html#object.__dir__) – Moe

18

Đây là một bổ sung thực tế cho câu trả lời của PierreBdR và Moe:

- cho Python> = 2.6 và các lớp kiểu mới, dir() có vẻ là đủ;
- cho các lớp học kiểu cũ, chúng ta ít nhất có thể làm những gì một standard module làm để hỗ trợ hoàn tab: ngoài việc dir(), tìm kiếm __class__ - và sau đó để đi cho __bases__ của nó:

# code borrowed from the rlcompleter module 
# tested under Python 2.6 (sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) \n[GCC 4.4.3]') 

# or: from rlcompleter import get_class_members 
def get_class_members(klass): 
    ret = dir(klass) 
    if hasattr(klass,'__bases__'): 
     for base in klass.__bases__: 
      ret = ret + get_class_members(base) 
    return ret 


def uniq(seq): 
    """ the 'set()' way (use dict when there's no set) """ 
    return list(set(seq)) 


def get_object_attrs(obj): 
    # code borrowed from the rlcompleter module (see the code for Completer::attr_matches()) 
    ret = dir(obj) 
    ## if "__builtins__" in ret: 
    ## ret.remove("__builtins__") 

    if hasattr(obj, '__class__'): 
     ret.append('__class__') 
     ret.extend(get_class_members(obj.__class__)) 

     ret = uniq(ret) 

    return ret 

(Mã kiểm tra và đầu ra bị xóa ngắn gọn nhưng về cơ bản đối với các đối tượng kiểu mới, chúng tôi có cùng kết quả cho get_object_attrs() như đối với dir() và đối với các lớp kiểu cũ, bổ sung chính cho đầu ra dir() dường như là thuộc tính __class__))

1

Đây là cách tôi đã làm nó, chỉ có ích cho các đối tượng tùy chỉnh đơn giản mà bạn giữ các thuộc tính thêm: cho một đối tượng obj tạo ra với obj = type("CustomObj",(object,),{}), hoặc bằng cách đơn giản:

class CustomObj(object): 
    pass 
obj=CustomObject() 

sau đó, để có được một cuốn từ điển chỉ với các thuộc tính tùy chỉnh, những gì tôi làm là:

{key: value for key, value in self.__dict__.items() if not key.startswith("__")} 
Các vấn đề liên quan