Откуда вы узнаете при просмотре списка атрибутов и методов, перечисленных в режиме, которые являются атрибутами, а какие - методы?

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

Вопрос

Я работаю над тем, чтобы научиться программировать в Python и сосредоточен на том, чтобы лучше справиться с тем, как использовать стандартные и другие модули. DIR -функция кажется действительно мощной в интерпретаторе, но мне интересно, что я что -то упускаю из -за отсутствия ООП. Используя книгу S.Lotts, я решил использовать его класс Die, чтобы узнать больше о синтаксисе и использовании классов и экземпляров.

Вот оригинальный код:

class Die(object):
''' simulate a six-sided die '''
def roll(self):
    self.value=random.randrange(1,7)
    return self.value
def getValue(self):
    return self.value

Я смотрел на это, и после создания некоторых случаев я задавался вопросом, является ли значение слов каким -то образом ключевым словом, и что использовало словесное объект в операторе класса, и поэтому я решил узнать, изменив определение класса на следующее:

class Die():
''' simulate a six-sided die '''
def roll(self):
    self.ban=random.randrange(1,7)
    return self.ban
def getValue(self):
    return self.ban

Это изменение показало мне, что я получил такое же поведение от моих экземпляров, но в тех случаях, когда я сделал режиссер: следующие методы/атрибуты отсутствовали:

'__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
 '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
_repr__', '__setattr__', '__str__', '__weakref__'

Я также понял, что, когда я поступил на режиме на экземпляр, у меня было дополнительное ключевое слово-запрет который я наконец понял, был атрибутом моего экземпляра. Это помогло мне понять, что я могу использовать D1.ban Чтобы получить доступ к значению моего экземпляра. Единственная причина, по которой я мог выяснить, что это был атрибут, я набрал D1.happy и получил Атрибут Я понял, что D1.getValue был методом, прикрепленным к смерти, потому что это то, что сказал мне переводчик.

Поэтому, когда я пытаюсь использовать какой -то сложный, но полезный модуль, такой как BeautifulSoup, как я могу узнать, какие из перечисленных вещей являются атрибутами моего экземпляра или методов моего экземпляра после печати Dir (экземпляр). Анкет Мне нужно было бы знать это, потому что этот ткнущий научил меня, что с атрибутами я называю результатом метода, и с помощью методов я вызываю функцию в своем экземпляре.

Этот вопрос, вероятно, слишком многословный, но он, безусловно, помог мне лучше понять разницу между атрибутами и методами. В частности, когда я смотрю на результат вызова DIR на экземпляр моего класса Die, я вижу

['__doc__', '__module__', 'ban', 'getValue', 'roll']

Таким образом, было бы полезно знать, просмотрев этот список, которые являются атрибутами и которые являются методами, не прибегая к проб и ошибкам или приводятся к печати в hasattr (myinstance, подозреваемый.

После публикации вопроса я попробовал

for each in dir(d1):
    print hasattr(d1,each)

что говорит мне строго говоря, что все методы являются атрибутами. Но я не могу назвать метод без () Поэтому мне кажется, что hasattr () вводит в заблуждение.

Это было полезно?

Решение

Вместо: "print hasattr(d1,each)", пытаться: "print each, type(getattr(d1,each))". Вы должны найти результаты информативными.

Также вместо dir() пытаться help(), что, я думаю, вы действительно ищете.

Другие советы

Подумайте об использовании стандартной библиотеки inspect Модуль-это часто самый лучший подход к самоанализу, упаковывая значительные куски функциональности (вы можете реализовать это с нуля, но многократно используя хорошо продуманную код-это хорошо). Видеть http://docs.python.org/library/inspect.html Для всех деталей, но, например, inspect.getmembers(foo, inspect.ismethod) это отличный способ получить все методы Foo (вы получите (name, value) Пары отсортированы по имени).

что говорит мне строго говоря, что все методы являются атрибутами. Но я не могу назвать метод без (), поэтому мне кажется, что hasattr () вводит в заблуждение.

Почему это вводит в заблуждение? Если obj.ban() это метод, тогда obj.ban соответствующий атрибут. Вы можете иметь подобный код:

print obj.getValue()

или же

get = obj.getValue
print get()

Если вы хотите получить список методов на объекте, вы можете попробовать эту функцию. Это не идеально, так как это также вызовет призывные атрибуты, которые не являются методами, но для 99% случаев должны быть достаточно хорошими:

def methods(obj):
    attrs = (getattr(obj, n) for n in dir(obj))
    return [a for a in attrs if a.hasattr("__call__")]

Этот info Модуль, вдохновленный погружением в Python, служит цели.

def info(obj, spacing=20, collapse=1, variables=False):
    '''Print methods and their doc Strings

    Takes any object'''
    if variables:
    methodList = [method for method in dir(obj)]
    else:
    methodList = [method for method in dir(obj) if callable(getattr(obj,method))]

    #print methodList


    print '\n'.join(['%s %s' %
            (method.ljust(spacing),
             " ".join(str(getattr(obj,method).__doc__).split()))
            for method in methodList])


if __name__=='__main__':
    info(list)

Существует встроенный метод, называемый Callable. Вы можете применить его к любому объекту, и он вернет true/false в зависимости от того, можно ли его вызвать. например

>>> def foo():
...   print "This is the only function now"
...
>>> localDictionary = dir()
>>> for item in localDictionary:
...   print repr(item) + "is callable: " + str(callable(locals()[item]))
'__builtins__'is callable: False
'__doc__'is callable: False
'__name__'is callable: False
'foo'is callable: True

Примечание. Вызов Locals () вернет словарь, содержащий все, что определено в вашей текущей области. Я сделал это, потому что элементы из словаря - это просто струны, и нам нужно запустить вызов на фактическом объекте.

В идеале, при использовании сложной библиотеки, такой как BeautifulSoup, вы должны проконсультироваться с его документацией, чтобы увидеть, какие методы предоставляет каждый класс. Тем не менее, в редком случае, когда у вас нет легкодоступной документации, вы можете проверить наличие методов, используя следующие.

Все методы, которые сами являются объектами, внедряют __call__ метод и может быть проверен с использованием метода Callible (), который возвращает True, если проверяемое значение имеет __call__ метод

Следующий код должен работать.

x = Die()
x.roll()

for attribute in dir(x) :
    print attribute, callable(getattr(x, attribute))

Приведенный выше код будет возвращать истину для всех методов и false для всех не вызывших атрибутов (например, таких членов данных, как запрет). Однако этот метод также возвращается True Для любых вызывших объектов (например, внутренних классов). Вы также можете проверить, является ли тип атрибута instancemethod

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top