1
class Vehicle:
    speed = 0
    def __init__(self, speed):
        self.speed = speed

    def drive(self, distance):
        print 'need %f hour(s)' % (distance / self.speed)

print dir(Vehicle)

The Pycharm shows: ['__doc__', '__init__', '__module__', 'drive', 'speed']

But given that 'speed' is a member data, 'drive' is a member function, why are there no brackets after 'drive'?

How can I distinguish data member and function member with dir() in python?

If dir() only lists attribute names, then how can I list all the data members and methods in a class?Otherwise, when I want to call an attribute, how do I know whether it needs parentheses after the attribute name or not?

Is there a function simply show all the data member and method in a class directly

youngtree
  • 53
  • 6
  • The semantics of `dir()` are very well defined. It is mostly meant to be used for convenience in interactive use. What are you trying to achieve? – Sven Marnach Jul 31 '17 at 14:18
  • As an aside: I would remove the `speed = 0` from outside the `__init__`, since I assume you want each vehicle to have its own speed. Check out [the difference between a class member and an instance member](https://stackoverflow.com/q/207000/198633) – inspectorG4dget Jul 31 '17 at 14:20
  • `dir()` lists attribute names, i.e. names that can be looked up on the object using `getattr(obj, name)`. An attribute name never contains parentheses, which is why they are not included. There also isn't a clear distinction between data members and methods, since functions are first-class values in Python. – Sven Marnach Jul 31 '17 at 14:20
  • Argh, this was supposed to be "The semantics of dir() are _not_ very well defined." – Sven Marnach Jul 31 '17 at 14:25
  • @SvenMarnach If dir() only lists attribute names, then how can I list all the data members and methods in a class?Otherwise, when I want to call an attribute, how do I know whether it needs parentheses after the attribute name or not? – youngtree Aug 01 '17 at 06:17
  • @user8394497 If you want to call an object, you always need parentheses, since that's the function call operator in Python. In general, you should look at the documentation of the library you are using or at the source code to understand how to use interfaces. – Sven Marnach Aug 01 '17 at 10:05

2 Answers2

2

To check if an attribute is a function, call type(attribute) will get you its type back.

import types
functions = (types.BuiltinFunctionType, types.BuiltinMethodType, types.FunctionType)
s = 'test'

for i in dir(s):
    attr_type = getattr(s, i)
    if isinstance(attr_type, functions):
        print i, attr_type

This will print you all the attributes which are functions.

EDIT: changed list compherension solution to isinstance builtin as suggested by Sven Marnach in the comments.

Chen A.
  • 10,140
  • 3
  • 42
  • 61
  • You should use the `callable()` built-in to check whether an object is callable. Your test breaks in some cases. – Sven Marnach Jul 31 '17 at 15:07
  • callable() will return true if an object implements `__call__`. Some classes implements this to make the objects callable, and they are not necessarily functions. From the doc `class instances are callable if they have a __call__() method.` Hence, callable here doesn't fit. And if you can please give an example when it breaks, so I can learn. – Chen A. Jul 31 '17 at 15:10
  • This very much depends on what the OP really wants. My reply in the comments was that there simply isn't a fundamental difference between data members and methods, so it all depends on what you are trying to achieve. An example where `hasattr(obj, '__call__')` does not work as expected is given here: https://stackoverflow.com/a/16388171/279627 – Sven Marnach Jul 31 '17 at 15:26
  • And more generally, if there is an official way of doing something, you should stick to it. For testing whether something is callable, use the built-in specifically made for this purpose. When checking whether and object has one of several types, use `isinstance(attr, tuple_of_type)`. – Sven Marnach Jul 31 '17 at 15:29
  • I agree, and that's the reason I edited my answer and provided a different solution. `hasattr(obj, '__call__')` doesn't fit here – Chen A. Jul 31 '17 at 15:29
  • If dir() only lists attribute names, then how can I list all the data members and methods in a class?Otherwise, when I want to call an attribute, how do I know whether it needs parentheses after the attribute name or not? – youngtree Aug 01 '17 at 06:18
  • @user8394497 `dir()` lists all attributes of an object, including variables and methods. If you want to know if an attribute is a method (hence the need for parenthesis) you can simply check `callable(obj.method)`. In my example, calling `callable(s.split)` returns True since split() is a method of str objects. – Chen A. Aug 01 '17 at 06:22
  • @Vinny thanks.If an attribute is a data member,will callable return false?Is there a function simply show all the data member and method in a class directly? – youngtree Aug 01 '17 at 06:52
  • @user8394497 if it's not callable, then it returns false. I'm not familiar with a such function – Chen A. Aug 01 '17 at 07:03
1

speed is a member data,drive is a member function, why there is no brackets after drive?

From help(dir):

...return an alphabetized list of names comprising (some of) the attributes of the given object, and of attributes reachable from it...

That being said, dir doesn't bear the responsibility of recognizing the differences between objects, instead it shows you the attributes that are accessible in a given namespace. However, Python is dynamic and you could very easily manipulate the results returned by dir, for example you could do use this under 3.X:

from types import FunctionType
allMethods = [] 

# get rid of builtin names: __str__, __repr__,... 
user_defined_objs = [name for name in dir(Vehicle) if not name.startswith("__")]  

for name in user_defined_objs:
    obj = getattr(Vehicle, name)
    if isinstance(obj, FunctionType): # function? 
        allMethods.append(name)

There's nothing special in this code.FunctionType is the class from which function objects are created. In 3.X, Vehicle.drive is a function, however, Vehicle().drive is a bound method, in 2.X this is slightly different. We just filter those objects according to their types. In 3.X, Vehicle.drive when referenced from the class not from an instance like: Vehicle().drive it's an instance of FunctionType.

GIZ
  • 4,409
  • 1
  • 24
  • 43
  • 1
    Did you mean `Vehicle.drive` and `Vehicle().drive` instead of `Vehicle.speed` and `Vehicle().speed`? – nanotek Jul 31 '17 at 17:26
  • @nanotek My bad, yes. – GIZ Jul 31 '17 at 17:28
  • If dir() only lists attribute names, then how can I list all the data members and methods in a class?Otherwise, when I want to call an attribute, how do I know whether it needs parentheses after the attribute name or not? – youngtree Aug 01 '17 at 06:18
  • @user8394497 Have you looked at the code I provided? `dir` lists all attributes that are accessible within a namespace (inherited attrs) _plus_ attrs within that namespace, *not just the attributes within that namespace. You could also use `callable` builtin function to check if an object is callable: `obj()`. Let me know if you're still confused. – GIZ Aug 01 '17 at 07:09