2011-05-26 14 views
5

Python için Java dan kod parçası dönüştürme ve ben şu çevirmek için nasıl bilmiyorum:Java'nın getClass() Python eşdeğer getFields()

Field[] fields = getClass().getFields(); 
    for (int i = 0; i < fields.length; i++) { 
     if (fields[i].getName().startsWith((String) param){ .... 
+0

ben 'getClass(). GetFields()' ne emin değilim, ama 'dir' baktım? 'a = myClass()' 'dir (a)' – inspectorG4dget

cevap

3

Bu kesin eşdeğer değil ama dir(self) başlamanıza gerek.

9

Python, sen örneğin __dict__ ile bir nesnenin bağlamaları sorgulayabilir:

Ayrıca
>>> class A: 
...  def foo(self): return "bar" 
... 
>>> A.__dict__ 
{'__module__': '__main__', 'foo': <function foo at 0x7ff3d79c>, '__doc__': None} 

, bu bir C# açısından istendi: How to enumerate an object's properties in Python?

yerine doğrudan __dict__ kullanarak yapabilirsiniz Öncelikle inspect.ismethod(object)

+2

'Inspect' modülü harika bir öneridir. Bununla birlikte, '__dict__' ile oynamayı öneremem, çünkü bir nesne özniteliklerini __slots__' tarafından tanımlanmış olabilir. Bunun iyi bir cevap olduğunu söylemiştim :) – brandizzi

+2

Ayrıca, '__dict__' içinde özellikler görünmüyor, bu yüzden' __slots__' kullanmıyor olsanız bile büyük olasılıkla kırılacak. Her şeye rağmen, 'inceleme' modülü bunlarla ilgilenir. –

6

gibi yararlı yöntemleri vardır ki, inspect.getmembers(object[, predicate]) kullanmak, bir ob çünkü Python getClass().getFields() diye bir şey olmadığını vurgulamak istiyorum Ject sınıf tarafından tanımlanmayan birçok alana sahip olabilir. Aslında, Python'da bir alan yaratmak için ona bir değer atfetmeniz yeterlidir. alanlar değil tanımlanan olan oluşturulan şunlardır:

>>> class Foo(object): 
...  def __init__(self, value): 
...   # The __init__ method will create a field 
...   self.value = value 
... 
>>> foo = Foo(42) 
>>> foo.value 
42 
>>> # Accessing inexistent field 
... foo.another_value 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
AttributeError: 'Foo' object has no attribute 'another_value' 
>>> # Creating the field 
... foo.another_value = 34 
>>> # Now I can use it 
... foo.another_value 
34 

Yani, bir sınıftan alanları alamadım. Bunun yerine, alanları bir nesneden alırsınız.

Ayrıca, Python yöntemleri yalnızca bazı özel değerleri olan alanlardır. Yöntemler sadece fonksiyonların örnekleri şunlardır:

>>> type(foo.__init__) 

O yanı yöntemleri dönecektir Python getClass().getMethods() diye bir yöntem ve getClass().getFields() ait "eşdeğer" olduğunu açıkça olmak için dikkat etmek önemlidir .

Dedi ki, tarlaları (veya Python'da sıkça çağrıldıkları gibi) nasıl elde edersiniz? Elbette onları sınıftan alamazsınız, çünkü nesneler onları saklar.

>>> getattr(foo, 'value') 
42 
: Eğer özellik adları aldığımda

>>> dir(foo) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'another_value', 'value'] 

, sen getattr() işlevini kullanarak bunların her alabilirsiniz: Yani adını dir() fonksiyonunu kullanarak bir nesnenin özelliklerinin alabilirsiniz

hepsini almak için, list comprehensions kullanabilirsiniz:

>>> [getattr(foo, attrname) for attrname in dir(foo)] 
[<class '__main__.Foo'>, <method-wrapper '__delattr__' of Foo object at 0x2e36b0>, 
{'another_value': 34, 'value': 42}, None, <built-in method __format__ of Foo object at 0x2e36b0>, 
<method-wrapper '__getattribute__' of Foo object at 0x2e36b0>, 
... # Lots of stuff 
34, 42] 

sonunda bazı özelliklerde ayarladığınız değerleri bulabilirsiniz. Ancak, bu listede de yöntemler bulunacaktır. Onların öznitelikleri olduğunu unutmayın.Bu durumda, bizim liste anlama önlemek çağrılabilir attrbutes yapabilirsiniz:

>>> [attrname for attrname in dir(foo) if not callable(getattr(foo, attrname))] 
['__dict__', '__doc__', '__module__', '__weakref__', 'another_value', 'value'] 

Şimdi, gerçek değerleri elde:

>>> [getattr(foo, attrname) for attrname in dir(foo) 
...  if not callable(getattr(foo, attrname))] 
[{'another_value': 34, 'value': 42}, None, '__main__', None, 34, 42] 

hala bazı garip değerleri var orada gibi __dict__, __doc__ vs. Göz ardı etmek isteyebileceğiniz bazı şeyler. Eğer öyleyse, sadece liste anlama başka kriterleri koyun:

>>> [attrname for attrname in dir(foo) 
...  if not attrname.startswith('__') and 
...   not callable(getattr(foo, attrname))] 
['another_value', 'value'] 
>>> [getattr(foo, attrname) for attrname in dir(foo) 
...  if not attrname.startswith('__') and 
...   not callable(getattr(foo, attrname))] 
[34, 42] 

böyle şeyler yapmak için başka yolları da vardır. Örneğin, bir nesnenin __dict__ ve __slots__ özniteliklerine bakabilirsiniz. Bununla birlikte, sunduğum yöntemin yeni başlayanlar için daha net olduğunu düşünüyorum.

EDIT İki nokta daha. İlk olarak, cls solution gerçekten iyi çünkü inspect module'a bakmanızı önerir.

Ayrıca, bir özniteliğin hem adını hem de değerini almak isteyebilirsiniz. Bunu tüp listeleriniz üreten alabilirsiniz:

>>> [(attrname, getattr(foo, attrname)) for attrname in dir(foo) 
...  if not attrname.startswith('__') and 
...   not callable(getattr(foo, attrname))] 
[('another_value', 34), ('value', 42)] 

Neyse ki, cls'ye önerdiği inspect.getmembers() işlevi yapar daha iyi.

>>> import inspect 
>>> inspect.getmembers(foo) 
[('__class__', <class '__main__.Foo'>), 
# ... Lots of stuff ... 
('another_value', 34), ('value', 42)] 

sadece callables önlemek, yöntemleri kaldırmak için:

>>> inspect.getmembers(foo, lambda attr: not callable(attr)) 
[('__dict__', {'another_value': 34, 'value': 42}), ('__doc__', None), ('__module__', '__main__'), ('__weakref__', None), ('another_value', 34), ('value', 42)] 

(beklediğim gibi maalesef inspect.ismethod() işe yaramadı.)

Orada henüz iç bir sürü ve biz yöntemlerle yaptığımız gibi doğrudan dışarı çıkamaz.

>>> [(name, value) for name, value in inspect.getmembers(foo, lambda attr: not callable(attr)) 
...   if not name.startswith('__')] 
[('another_value', 34), ('value', 42)] 

Python çok dinamik bir dildir ve bu çözüm bazı durumlarda hem çalışamaz: Liste kavraması tekrar çözebilir şey yok. Bir yerde kullanılması için bir işlevi saklaması gereken bir nesneye sahip olabileceğini düşünün. Bir işlev, çağrılabilir bir nesnedir ve özellik sunulmaz. Ancak, mantıksal olarak bir öznitelik, kullanılacak bir veridir. Aklında bu tür şeyler olmalı. Ancak, bahse girerim bu tür sorunları çok sık alamayacaksınız.

HTH