العثور على الأساليب التي يمتلكها كائن بايثون

StackOverflow https://stackoverflow.com/questions/34439

  •  09-06-2019
  •  | 
  •  

سؤال

بالنظر إلى كائن بايثون من أي نوع، هل هناك طريقة سهلة للحصول على قائمة بجميع الأساليب التي يحتوي عليها هذا الكائن؟

أو،

إذا لم يكن ذلك ممكنًا، فهل هناك على الأقل طريقة سهلة للتحقق مما إذا كان لديه طريقة معينة بخلاف مجرد التحقق من حدوث خطأ عند استدعاء الطريقة؟

هل كانت مفيدة؟

المحلول

يبدو أنه يمكنك استخدام هذا الرمز، واستبدال "الكائن" بالكائن الذي تهتم به:

object_methods = [method_name for method_name in dir(object)
                  if callable(getattr(object, method_name))]

لقد اكتشفت ذلك في هذا الموقع.نأمل أن يوفر ذلك بعض التفاصيل الإضافية!

نصائح أخرى

يمكنك استخدام المدمج في dir() وظيفة للحصول على قائمة بجميع السمات التي تمتلكها الوحدة.جرب هذا في سطر الأوامر لترى كيف يعمل.

>>> import moduleName
>>> dir(moduleName)

كما يمكنك استخدام hasattr(module_name, "attr_name") وظيفة لمعرفة ما إذا كانت الوحدة لها سمة محددة.

انظر دليل لاستبطان بايثون للمزيد من المعلومات.

أبسط طريقة هي الاستخدام dir(objectname).سيتم عرض كافة الأساليب المتاحة لهذا الكائن.خدعة باردة.

للتحقق مما إذا كان لديه طريقة معينة:

hasattr(object,"method")

أعتقد أن ما تريده هو شيء من هذا القبيل:

قائمة السمات من كائن

في رأيي المتواضع، الوظيفة المضمنة dir() يمكن أن أقوم بهذه المهمة نيابة عنكمأخوذ من help(dir) الإخراج على Python Shell الخاص بك:

دير (...)

dir([object]) -> list of strings

إذا تم استدعاؤها بدون وسيطة، قم بإرجاع الأسماء الموجودة في النطاق الحالي.

بخلاف ذلك، قم بإرجاع قائمة مرتبة أبجديًا بالأسماء التي تتضمن (بعضًا) سمات الكائن المحدد والسمات التي يمكن الوصول إليها منه.

إذا كان الكائن يوفر طريقة تسمى __dir__, ، سيتم استخدامه؛وإلا يتم استخدام منطق Dir () الافتراضي ويعود:

  • لكائن الوحدة النمطية:سمات الوحدة.
  • لكائن فئة:صفاته، وتكرار صفات قواعده.
  • لأي كائن آخر:سماتها ، سمات فئتها ، وكرات متكررة لفئات قاعدة فئتها.

على سبيل المثال:

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> a = "I am a string"
>>>
>>> type(a)
<class 'str'>
>>>
>>> dir(a)
['__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']

بينما كنت أتحقق من مشكلتك، قررت أن أعرض سلسلة أفكاري، من خلال تنسيق أفضل لمخرجات dir().

dir_attributes.py (بايثون 2.7.6)

#!/usr/bin/python
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print "\nObject Data: %s" % obj
print "Object Type: %s\n" % type(obj)

for method in dir(obj):
    # the comma at the end of the print, makes it printing 
    # in the same line, 4 times (count)
    print "| {0: <20}".format(method),
    count += 1
    if count == 4:
        count = 0
        print

dir_attributes.py (بايثون 3.4.3)

#!/usr/bin/python3
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print("\nObject Data: ", obj)
print("Object Type: ", type(obj),"\n")

for method in dir(obj):
    # the end=" " at the end of the print statement, 
    # makes it printing in the same line, 4 times (count)
    print("|    {:20}".format(method), end=" ")
    count += 1
    if count == 4:
        count = 0
        print("")

أتمنى أن أكون قد ساهمت :).

علاوة على الإجابات الأكثر مباشرة، سأكون مقصرا إذا لم أذكرها آي بايثون.اضغط على "علامة التبويب" لرؤية الطرق المتاحة، مع الإكمال التلقائي.

وبمجرد العثور على طريقة، حاول:

help(object.method) 

لرؤية pydocs، وتوقيع الطريقة، وما إلى ذلك.

اه... ردل.

إذا كنت تريد على وجه التحديد طُرق, ، يجب عليك استخدام Inspector.ismethod.

لأسماء الطريقة:

import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]

بالنسبة للطرق نفسها:

import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]

أحيانا inspect.isroutine يمكن أن يكون مفيدًا أيضًا (للمكونات الإضافية وامتدادات C وCython بدون توجيه المترجم "الملزم").

افتح bash Shell (ctrl+alt+T على Ubuntu).ابدأ تشغيل غلاف python3 فيه.إنشاء كائن لمراقبة أساليب.ما عليك سوى إضافة نقطة بعدها والضغط مرتين على "tab" وسترى شيئًا كهذا:

 user@note:~$ python3
 Python 3.4.3 (default, Nov 17 2016, 01:08:31) 
 [GCC 4.8.4] on linux
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import readline
 >>> readline.parse_and_bind("tab: complete")
 >>> s = "Any object. Now it's a string"
 >>> s. # here tab should be pressed twice
 s.__add__(           s.__rmod__(          s.istitle(
 s.__class__(         s.__rmul__(          s.isupper(
 s.__contains__(      s.__setattr__(       s.join(
 s.__delattr__(       s.__sizeof__(        s.ljust(
 s.__dir__(           s.__str__(           s.lower(
 s.__doc__            s.__subclasshook__(  s.lstrip(
 s.__eq__(            s.capitalize(        s.maketrans(
 s.__format__(        s.casefold(          s.partition(
 s.__ge__(            s.center(            s.replace(
 s.__getattribute__(  s.count(             s.rfind(
 s.__getitem__(       s.encode(            s.rindex(
 s.__getnewargs__(    s.endswith(          s.rjust(
 s.__gt__(            s.expandtabs(        s.rpartition(
 s.__hash__(          s.find(              s.rsplit(
 s.__init__(          s.format(            s.rstrip(
 s.__iter__(          s.format_map(        s.split(
 s.__le__(            s.index(             s.splitlines(
 s.__len__(           s.isalnum(           s.startswith(
 s.__lt__(            s.isalpha(           s.strip(
 s.__mod__(           s.isdecimal(         s.swapcase(
 s.__mul__(           s.isdigit(           s.title(
 s.__ne__(            s.isidentifier(      s.translate(
 s.__new__(           s.islower(           s.upper(
 s.__reduce__(        s.isnumeric(         s.zfill(
 s.__reduce_ex__(     s.isprintable(       
 s.__repr__(          s.isspace(           

المشكلة في جميع الطرق المشار إليها هنا هي أنه لا يمكنك التأكد من عدم وجود الطريقة.

في بايثون يمكنك اعتراض استدعاء النقطة من خلال __getattr__ و __getattribute__, ، مما يجعل من الممكن إنشاء طريقة "في وقت التشغيل"

مثال:

class MoreMethod(object):
    def some_method(self, x):
        return x
    def __getattr__(self, *args):
        return lambda x: x*2

إذا قمت بتنفيذها، يمكنك استدعاء الطريقة غير الموجودة في قاموس الكائنات...

>>> o = MoreMethod()
>>> o.some_method(5)
5
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method']
>>> o.i_dont_care_of_the_name(5)
10

ولهذا السبب تستخدم فالاستغفار أسهل من الاستئذان النماذج في بايثون.

إن أبسط طريقة للحصول على قائمة بأساليب أي كائن هي استخدامها help() يأمر.

%help(object)

سيقوم بسرد جميع الطرق المتاحة/المهمة المرتبطة بهذا الكائن.

على سبيل المثال:

help(str)

يمكن للمرء إنشاء getAttrs الدالة التي ستعيد أسماء الخصائص القابلة للاستدعاء للكائن

def getAttrs(object):
  return filter(lambda m: callable(getattr(object, m)), dir(object))

print getAttrs('Foo bar'.split(' '))

هذا سيعود

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
 '__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__', 
 '__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__', 
 '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
 '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', 
 '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 
 'remove', 'reverse', 'sort']

لا توجد طريقة موثوقة لسرد كافة أساليب الكائن. dir(object) عادةً ما يكون مفيدًا، ولكن في بعض الحالات قد لا يسرد جميع الطرق.وفق dir() توثيق: "بحجة، محاولة لإرجاع قائمة بالسمات الصالحة لهذا الكائن."

يمكن التحقق من وجود هذه الطريقة عن طريق callable(getattr(object, method)) كما سبق ذكره هناك.

...هل هناك على الأقل طريقة سهلة للتحقق مما إذا كانت تحتوي على طريقة معينة بخلاف مجرد التحقق من حدوث خطأ عند استدعاء الطريقة

بينما "فالاستغفار أسهل من الاستئذان" هي بالتأكيد الطريقة البايثونية، ربما ما تبحث عنه:

d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
    d.get('foo')
# OUT: 'bar'

خذ قائمة ككائن

obj = []

list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))

لقد حصلت:

['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']

من أجل البحث عن طريقة محددة في وحدة كاملة

for method in dir(module) :
  if "keyword_of_methode" in method :
   print(method, end="\n")
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top