eligro
eligro

Reputation: 845

print out the class parameters on python

class FooTable(Base):

    Id = Column(BIGINT, primary_key=True)
    name = Column(VARCHAR(256), nullable=False)
    username = Column(VARCHAR(256), nullable=False)
    state = Column(VARCHAR(100), nullable=False)
    city = Column(VARCHAR(256), nullable=False)
    zip = Column(VARCHAR(100), nullable=False)

I want to print out the instantiation arguments of class Column. generally- python code to string. example:

for k, v in vars(FooTable).iteritems():
      print k, get_class_attr(v)


>>> Id ["BIGINT", "primary_key=True"]
>>> name ["VARCHAR(256)", "nullable=False"]
    ...

I tried the inspect module, but found that it does not support it: http://docs.python.org/library/inspect.html#inspect.getmembers

Thanks for any information

Upvotes: 2

Views: 8630

Answers (5)

Burhan Khalid
Burhan Khalid

Reputation: 174622

I think you are looking for this:

>>> class Foo:
...    def bar(a,b,c):
...       pass
...
>>> x = Foo()
>>> x.bar.func_code.co_varnames
('a', 'b', 'c')

Here is another attempt, and I think this does what you need; although its a bit convoluted.

>>> class Foo:
...    a = 'b'
...    def bar(y,z):
...       pass
... 

>>> funcs = [(i,getattr(Foo,i).func_code.co_varnames) for i in dir(Foo) \
...          if hasattr(getattr(Foo,i),'func_code')]
>>> 
>>> funcs
[('bar', ('y', 'z'))]

However if you want to know what arguments were passed to a class, then from the instance, use __dict__.

>>> class Foo:
...    a = ''
...    def __init__(self, b, c):
...        self.a = b
...        self.c = c
... 
>>> funcs = [(i,getattr(Foo,i).func_code.co_varnames) for i in dir(Foo) if hasattr(getattr(Foo,i),'func_code')]
>>> funcs
[('__init__', ('self', 'b', 'c'))]
>>> i = Foo(1,2)
>>> i.__dict__
{'a': 1, 'c': 2}

Upvotes: 0

rantanplan
rantanplan

Reputation: 7450

Actually what you are asking for, doesn't make much sense. Burhan Khalid's answer is close, but not really. You want the actual arguments that the caller passed when instantiating the class. Not the function's/constructor's signature.

But this is book keeping that the class' programmer should do on his own. And even then, he wouldn't actually do that. He would configure each instance based on the passed parameters.

e.g.

class Foo(object):
    def __init__(self, *args, **kwargs):
        self.is_cool = kwargs.get('whatever', False)

And then I would check the instance attribute:

f = Foo()
f.is_cool   # False

and I would try to make sense of it, depending on what this means for my instance.

But I don't really care about the actual parameters passed. My instance will configure itself based on what was passed.

You could of course write a class decorator that wraps any 3rd party Class and do exactly what you need, but it is an overhead that doesn't seem justifiable in this case.

Upvotes: 1

Mikhail Karavashkin
Mikhail Karavashkin

Reputation: 1365

I'd suggest using __dict__ and then filterting its output as dir won't work with metaclasses either.

def filterFunction(field):
    '''
    This is a sample filtering function
    '''
    name, value = field
    return not name.startswith("_")

for k, v in vars(FooTable).iteritems():
      print k, filter(filterFunction, v.__dict__.items())

For that case for the following class

class X():
  foo = "bar"
  baz = True

Our filter

filter(filterFunction, X.__dict__.items())

would return

[('foo', 'bar'), ('baz', True)]

To get instantiation parameters, i'd check whether field name is in Column.__init__.im_self

Upvotes: 3

Burhan Khalid
Burhan Khalid

Reputation: 174622

attrs = [i for i in dir(obj) if not i.startswith('_')]

Keep in mind that attributes that begin with _ are generally considered "private". Here is a sample run:

>>> [i for i in dir(4) if not i.startswith('_')]
['conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> [i for i in dir('') if not i.startswith('_')]
['capitalize', 'center', ... 'split', 'splitlines', ... 'upper', 'zfill']
>>> class Foo:
...    a = 'Hello'
...    def __init__(self):
...      pass
...    def hello(self):
...      print 'Hello'
...
>>> [i for i in dir(Foo) if not i.startswith('_')]
['a', 'hello']

Upvotes: 0

Iulius Curt
Iulius Curt

Reputation: 5114

You can print the attributes of a class with:

print dir( Column )

This is if I correctly understand your question

Upvotes: 0

Related Questions