Lời khuyên về Python: Tính di động của lệnh gọi hàm nội tâm


14

Trong Python, bạn có thể sử dụng dirhàm trên bất kỳ đối tượng nào để có danh sách tên của các hàm đối tượng của nó:

>>> dir('abc')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__','__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

Tôi tự hỏi liệu đây có phải là một kỹ thuật chơi gôn hữu ích trong một chương trình hơn là gọi một số chức năng được đặt tên dài. Trong trường hợp như vậy, tôi có thể tạo một chức năng lựa chọn chức năng F:

F=lambda o,i:eval('o.'+dir(o)[i])

Bây giờ giả sử tôi có một chuỗi svà tôi muốn lưu trữ kết quả viết hoa chữ cái đầu tiên của nó trong biến c. Sau đó, thay vì c=s.capitalize(),tôi có thể lưu ý rằng đó capitalizelà ở vị trí 33 trong danh sách trên và làm như sau:

s='abc'
c=G(s,33)()

mà gán 'Abc'cho c.

Câu hỏi của tôi là liệu điều này có khả năng làm việc hầu hết thời gian. Đặc biệt,

  • Tôi có thể luôn luôn dựa vào danh sách được sắp xếp theo từ vựng theo các giá trị ASCII không?
  • Có nhiều thay đổi trong danh sách có sẵn giữa các phiên bản nhỏ?
  • Có sự khác biệt tồn tại giữa các thực hiện?

Ngoài ra, có ai đã sử dụng điều này trước đây trên PPCG chưa?


Tôi đã thấy những điều tương tự được thực hiện với JavaScript và C #.
Peter Taylor

2
Bạn cũng có thể làm điều này với nội dung : dir(__builtins__). Và đây là một chức năng thay thế : F=lambda o,i:getattr(o,dir(o)[i]).
grc

Cũng lưu ý rằng tùy thuộc vào chức năng bạn dự định sử dụng, bạn có thể thêm ()phần cuối vào Fnhư vậy: F=lambda o,i:eval('o.'+dir(o)[i])()Sau đó c=F('abc',33)sẽ gán 'Abc' cho c.
FryAmTheEggman

Câu trả lời:


6

Từ tài liệu :

Danh sách kết quả được sắp xếp theo thứ tự abc

Về sự khác biệt, tôi nghĩ bạn sẽ phải kiểm tra (và chỉ định trong câu trả lời của bạn có lẽ là một ý tưởng tốt). Chẳng hạn, có sự khác biệt rõ ràng giữa python 2 và 3, __nonzero__được đổi tên thành __bool__.

Tôi chưa bao giờ nghe về bất kỳ sự khác biệt giữa các triển khai, nhưng tôi không thể tìm thấy bất kỳ tài liệu tham khảo nào về điều này.

Tôi không nghĩ rằng điều này đã được sử dụng trước đây một phần bởi vì nó sẽ hiếm khi giúp bạn tiết kiệm bất kỳ nhân vật nào khi làm một việc như:

F=str.capitalize
s='abc'
c=F(s)

Bạn sẽ cần phải sử dụng một số chức năng khác nhau dir()để có giá trị này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.