views:

358

answers:

8

Unless I'm mistaken, creating a function in Python works like this

def my_func(param1, param2):
    # stuff

However, you don't actually give the types of those parameters. Also, if I remember, python is a strongly typed language, as such, it sesms like Python shouldn't let you pass in a parameter of a different type then the function creator expected. However, how does Python know that the user of the function is passing in the proper types? Or will the program just die if it's the wrong type, assuming the function actually uses the parameter? Or do you have to specify the type/I'm missing something?

Thank you.

+4  A: 

Python is not strongly typed in the sense of static or compile-time type checking.

Most Python code falls under so-called "Duck Typing" -- for example, you look for a method read on an object -- you don't care if the object is a file on disk or a socket, you just want to read N bytes from it.

Mark Rushakoff
Python _is_ strongly typed. It is also dynamically typed.
Daniel Newby
+1  A: 

You never specify the type; Python has the concept of duck typing; basically the code that processes the parameters will make certain assumptions about them - perhaps by calling certain methods that a parameter is expected to implement. If the parameter is of the wrong type, then an exception will be thrown.

In general it is up to your code to ensure that you are passing around objects of the proper type - there is no compiler to enforce this ahead of time.

Justin Ethier
+2  A: 

You don't specify a type. The method will only fail (at runtime) if it tries to access attributes that are not defined on the parameters that are passed in.

So this simple function:

def no_op(param1, param2):
    pass

... will not fail no matter what two args are passed in.

However, this function:

def call_quack(param1, param2):
    param1.quack()
    param2.quack()

... will fail at runtime if param1 and param2 do not both have callable attributes named quack.

TM
+1: The attributes and methods are not determined statically. The concept of how would this "proper type" or "wrong type" are established by whether or not the type works properly in the function.
S.Lott
+1  A: 

Python doesn't care what you pass in to its functions. When you call my_func(a,b), the param1 and param2 variables will then hold the values of a and b. Python doesn't know that you are calling the function with the proper types, and excepts the programmer to take care of that. If your function will be called with different types of parameters, you can wrap code accessing them with try/except blocks and evaluate the parameters in whatever way you want.

Kyle
Python does not have variables, like other languages where variables have a type and a value; it has *names* pointing to *objects*, which know their type.
ΤΖΩΤΖΙΟΥ
+1  A: 

As Alex Martelli explains,

The normal, Pythonic, preferred solution is almost invariably "duck typing": try using the argument as if it was of a certain desired type, do it in a try/except statement catching all exceptions that could arise if the argument was not in fact of that type (or any other type nicely duck-mimicking it;-), and in the except clause, try something else (using the argument "as if" it was of some other type).

Read the rest of his post for helpful information.

Nick Presta
+8  A: 

Python is strongly typed because every object has a type, every object knows its type, it's impossible to accidentally or deliberately use an object of a type "as if" it was an object of a different type, and all elementary operations on the object are delegated to its type.

This has nothing to do with names. A name in Python doesn't "have a type": if and when a name's defined, the name refers to an object, and the object does have a type (but that doesn't in fact force a type on the name: a name is a name is a name).

A name in Python can perfectly well refer to different objects at different times (as in most programming languages, though not all) -- and there is no constraint on the name such that, if it has once referred to an object of type X, it's then forevermore constrained to refer only to other objects of type X. Constraints on names are not part of the concept of "strong typing", though some enthusiasts of static typing (where names do get constrained, and in a static, AKA compile-time, fashion, too) do misuse the term this way.

Alex Martelli
+1, better than my answer
TM
+2  A: 

In python everything has a type. Python function will do anything it is asked to do if the type of arguments support it.

Example: foo will add everything that can be __add__ed ;) without worrying much about its type. So that means ,to avoid failure ,you should provide only those things that support addition.

def foo(a,b):
    return a + b

class Bar(object):
    pass

class Zoo(object):
    def __add__(self,other):
        return 'zoom'

if __name__=='__main__':
    print foo(1,2)
    print foo('james','bond')
    print foo(Zoo(),Zoo())
    print foo(Bar(),Bar()) # should fail
TheMachineCharmer
A: 

Many languages have variables, which are of a specific type and have a value. Python does not have variables; it has objects, and you use names to refer to these objects.

In other languages, when you say:

a = 1

then a (typically integer) variable changes its contents to the value 1.

In Python,

a = 1

means “use the name a to refer to the object 1”. You can do the following in an interactive Python session:

>>> type(1)
<type 'int'>

The function type is called with the object 1; since every object knows its type, it's easy for type to find out said type and return it.

Likewise, whenever you define a function

def funcname(param1, param2):

the function receives two objects, and names them param1 and param2, regardless of their types. If you want to make sure the objects received are of a specific type, code your function as if they are of the needed type(s) and catch the exceptions that are thrown if they aren't. The exceptions thrown are typically TypeError (you used an invalid operation) and AttributeError (you tried to access an inexistent member (methods are members too) ).

ΤΖΩΤΖΙΟΥ