I would like to call a method to give me a dict of all of the "non-private" (I use the term "private" somewhat loosely here since it does not really exist in Python) and non-builtin attributes (i.e. those that do not begin with a single or double underscore) on a class. Something like vars(MyClass) that would return only the "public" attributes on that class.
I'm aware that
from M import *
does not import objects whose name starts with an underscore. (http://www.python.org/dev/peps/pep-0008/#id25) How does import implement that? Via a builtin function or just by checking for underscores? What is the pythonic way to do this?
Example:
class MyClass(object):
def __init__(self):
do_stuff()
def _private(self):
print 'private'
def __gets_name_mangled(self:
print 'becomes _MyClass__gets_name_mangled()'
def public(self):
print 'public'
If I do
vars(MyClass).keys()
I get
['_MyClass__gets_name_mangled', '__module__', '_private', '__doc__', '__dict__', '__weakref__', 'public', '__init__']
How can I get only
['public']
Or do I just need to check for underscores myself? It just seems like there would be a pythonic way to do this.
For more on underscores and double underscores, see: What is the meaning of a single- and a double-underscore before an object name?
To list all the attributes of an object, use the built-in dir() function. It returns a long list of attribute names, that is, method and variable names of the object.
Attributes of a class can also be accessed using the following built-in methods and functions : getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute.
In Python, there is no existence of Private methods that cannot be accessed except inside a class. However, to define a private method prefix the member name with the double underscore “__”. Note: The __init__ method is a constructor and runs as soon as an object of a class is instantiated.
Answer: Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself. Private access modifier is more secure and restrictive access level, whereas class and interfaces cannot be private.
With a dict comprehension that filters vars()
{ k:v for k,v in vars(myObject).items() if not k.startswith('_') }
Moved into a function that returns a list of attributes that are not 'soft private' or callables. You can return values if you like by changing to dict comprehension as above
def list_public_attributes(input_var):
return [k for k, v in vars(input_var).items() if
not (k.startswith('_') or callable(v))]
Actually, it would be unpythonic for such function to exists - because "officially" there is no private or protected fields/properties in Python.
While it makes sense to throw away module attributes with leading underscores (which are usually some implementation details) during import *
from some module*, it is not useful in context of any other object.
So, if you need to list only "public" methods/attributes of an object, just iterate through result of dir
and drop names with leading underscores.
* "during import *
from some module'"
Usually it is not the best practice. Consider the next example:
module A
has a1
and a2
defined
module B
has b1
and b2
defined
This code in module C
works as expected:
from A import a1, a2
from B import *
Imagine we add function a1
in module B
. Now suddenly module C
is broken, although we haven't touched it.
I'm using this function:
def print_all_public_fields(obj):
print(obj)
for a in dir(obj):
if not a.startswith('_') and not a.isupper():
print('\t%s = %s' % (a, getattr(obj, a)))
I know it's not exactly what you want, but maybe it'll give you some idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With