Iterare su un Python / IronPython Metodi dell'Oggetto
-
06-09-2019 - |
Domanda
Qual è il modo corretto per eseguire un ciclo di un oggetto Python metodi e la loro chiamata?
Dato l'oggetto:
class SomeTest():
def something1(self):
print "something 1"
def something2(self):
print "something 2"
Nessuna soluzione corretta
Altri suggerimenti
È possibile utilizzare il modulo di ispezionare per ottenere i membri della classe (o istanza):
>>> class C(object):
... a = 'blah'
... def b(self):
... pass
...
...
>>> c = C()
>>> inspect.getmembers(c, inspect.ismethod)
[('b', <bound method C.b of <__main__.C object at 0x100498250>>)]
getmembers () restituisce una lista di tuple, dove ogni tupla è (nome, utente). Il secondo argomento getmembers () è il predicato, che filtra la lista ritorno (in questo caso, tornando solo oggetti metodo)
Metodi vs. funzioni e altri tipi di oggetti chiamabili ...
(Per affrontare la questione nei commenti nel post di sconosciuta.)
In primo luogo, va rilevato che, oltre ai metodi definiti dall'utente, esistono metodi incorporati, e un metodo incorporato è, come doc all'indirizzo http://docs.python.org/reference/datamodel.html dice, "in realtà un diverso travestimento di una funzione built-in"( che è un involucro intorno una funzione C.)
Per quanto riguarda i metodi definiti dall'utente, come citazione citato si sa, dice:
A combina metodo oggetti definiti dall'utente una classe, un'istanza di classe (o None) e qualsiasi oggetto chiamabile (normalmente una funzione definita dall'utente).
Ma questo non significa che "tutto ciò che definisce __call__
ed è attaccato a un oggetto è un metodo." Un metodo è una richiamabile, ma richiamabile non è necessariamente un metodo. Metodi definiti dall'utente sono wrapper attorno a ciò che dice la citazione.
Speriamo che questa uscita (da Python 2.5.2 che ho a portata di mano) mostrerà la distinzione:
IDLE 1.2.2
>>> class A(object):
x = 7
>>> A # show the class object
<class '__main__.A'>
>>> a = A()
>>> a # show the instance
<__main__.A object at 0x021AFBF0>
>>> def test_func(self):
print self.x
>>> type(test_func) # what type is it?
<type 'function'>
>>> dir(test_func) # what does it have?
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__module__', '__name__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict',
'func_doc', 'func_globals', 'func_name']
>>> # But now let's put test_func on the class...
>>> A.test = test_func
>>> type(A.test) # What type does this show?
<type 'instancemethod'>
>>> dir(A.test) # And what does it have?
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class',
'im_func', 'im_self']
>>> # See, we just got a wrapper, and the function is in 'im_func'...
>>> getattr(A.test, 'im_func')
<function test_func at 0x0219F4B0>
>>> # Now to show bound vs. unbound methods...
>>> getattr(a.test, 'im_self') # Accessing it via the instance
<__main__.A object at 0x021AFBF0>
>>> # The instance is itself 'im_self'
>>> a.test()
7
>>> getattr(A.test, 'im_self') # Accessing it via the class returns None...
>>> print getattr(A.test, 'im_self')
None
>>> # It's unbound when accessed that way, so there's no instance in there
>>> # Which is why the following fails...
>>> A.test()
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
A.test()
TypeError: unbound method test_func() must be called with A instance as
first argument (got nothing instead)
>>>
E - editing per aggiungere il seguente output supplementare, che è rilevante anche ...
>>> class B(object):
pass
>>> b = B()
>>> b.test = test_func # Putting the function on the instance, not class
>>> type(b.test)
<type 'function'>
>>>
I wont aggiungo di più in uscita, ma si potrebbe anche fare una classe un attributo di un'altra classe o istanza, e, anche se le classi sono callable, non si ottiene un metodo. I metodi sono realizzati tramite i descrittori non di dati, in modo da guardare in alto descrittori se volete maggiori informazioni su come funzionano.
Questo frammento di codice chiamerà qualsiasi cosa troverà in obj
e memorizzare i risultati in mappatura, dove la chiave è nome attributo - dict((k, v()) for (k, v) in obj.__dict__.iteritems() if k.startswith('something'))
Modifica
Daniel, è sbagliato.
http://docs.python.org/reference/datamodel.html
Metodi definiti dall'utente
Definito dall'utente metodo oggetto combina una classe, di un'istanza della classe (o Nessuno) e qualsiasi oggetto callable (normalmente una funzione definita dall'utente).
Dunque, tutto ciò che definisce __call__ ed è allegato ad un oggetto è un metodo.
Risposta
Il modo corretto di vedere quali sono gli elementi di un oggetto è quello di utilizzare la funzione dir ().
Ovviamente questo esempio funziona solo per le funzioni che non prendono argomenti.
a=SomeTest()
for varname in dir(a):
var = getattr(a, varname)
if hasattr(var, "__call__"):
var()