Mercurial > js4py
view source/know-in-python.rst @ 213:0ea90a1819c2 default tip
Custom theming
| author | Radomir Dopieralski <radomir.dopieralski@allegro.pl> |
|---|---|
| date | Wed, 27 Jun 2012 16:35:54 +0200 |
| parents | 4e6cfa066d1a |
| children |
line wrap: on
line source
What do you need to know in Python ================================== Global and local scopes ----------------------- Whenever you reference a name in Python, it looks for it in several scopes. First it tries to find it in the *local* scope, which is usually the body of the function that is being currently executed. If the name is not there, Python tries the *global* scope, which is the body of the module. When that fails, it tries the *buildins*. .. code-block:: python import os # The name *os* gets defined in the *global* scope. g = 3 # Define variable *g* in the *global* scope with value 3. def my_function(x): # The name *x* gets defined in *local* scope of *my_function* # *x* is found in the *local* scope and its value is # assigned to new variable *y* created in *local* scope. y = x # The name *os* is not found in the *local* scope, so the *global* # scope is tried. A new variable *os* is created in the *local* scope # with value of the *os* from the *global* scope. os = os # The name *g* from *global* scope is imported into the *local* scope. global g # The *global* variable *g* is assigned the value of *local* # variable *x* g = x my_function(3) In JavaScript you have a whole hierarchy of scopes -- each new nested function creates a new scope. The scopes are searched beginning from the innermost up to the global object. Default scope ------------- In Python, when you create a new name, it goes by default to the *local* scope (when you are at the module scope, it's equal to the *global* scope). You don't need to do anything special to make that happen. In JavaScript, variables go to the global object by default. You have to use the ``var`` keyword to have them defined locally. Functions passed as parameters ------------------------------ Everything is an object in Python. In particular, a function is an object. This means that you can assign a function to a variable or pass it as a function argument. This may be useful when you want to have some generic algorithms. This is used in the ``sort`` method so that you can, for example, sort strings in case-insensitive way: .. code-block:: python def lowercase(s): return s.lower() my_list = ['a', 'B', 'c'] my_list.sort(key=lowercase) print my_list You can pass functions as parameters and assign them to variables in JavaScript too, although there is one important detail that is different about methods. Method binding -------------- Methods in Python are bound to object instances. This means that you can pass them around as shown above, and they will still remember what object they belong to. .. code-block:: python def call_with_a(method): method('a') my_list = [] call_with_a(my_list.append) print my_list This is not true for JavaScript. In JavaScript the functions and methods don't know where they came from, and they get the reference to their object at the moment when they are called. Closures -------- You can define a function inside other function in Python. That new function then has access to all the variables in the local scope of the initial function. Moreover, if you return that new function from the original function, all the variables in the original function's scope are still alive -- because the new function still has access to them. This saved scope is called a closure. An example use of a closure is a "private" variable that can be only accessed by ``get`` and ``set`` functions. .. code-block:: python def create_get_set(): """ Get a pair of functions for getting and setting a hidden value. Using a closure. """ value = None def get(): return value def set(new_value): value = new_value return get, set The ``value`` variable stays in the memory even after ``create_get_set`` finishes, because the ``get`` and ``set`` functions still hold a reference to it. Because they are the only objects holding reference to it, the variable is effectively hidden from other code. You could have a similar effect by using an object: .. code-block:: python class GetSet(object): def __init__(self): self.value = None def get(self): return self.value def set(self, new_value): self.value = new_value def create_get_set(): """ Get a pair of functions for getting and setting a hidden value. Using a closure. """ getset = GetSet() return getset.get, getset.set Here instead of a closure we have an explicit ``getset`` object. Again, this object stays in memory because the bound methods ``get`` and ``set`` hold a reference to it. This couldn't be done in JavaScript. Star arguments -------------- You can define a function that takes a variable number of arguments: .. code-block:: python def average(*args): total = 0 for arg in args: total += arg return float(total)/len(args) And you can even have a function that takes keyword arguments: .. code-block:: python def get_arguments(*args, **kwargs): return args, kwargs get_argumenst(1, 2, 3, four=5) You can also call a function and pass it a dictionary or list as the argument: .. code-block:: python my_list = [1, 2, 3] my_dict = {'four': 5} get_arguments(*my_list, **my_dict) In JavaScript there are other mechanisms for doing that: the *arguments* keyword has the list of all parameters passed to a function. These are all positional arguments, JavaScript doesn't have keyword arguments. The *apply* method of a function lets you pass an array of parameters in a function call.
