【鼎革‧革鼎】︰ Raspbian Stretch 《六之 J.2A 》

人類能夠『獨立思考』嗎?人們講︰因為他『如此說』,所以我『這般信』,難到這果是『合理』的嗎??還是這真的『不合理』的呢???就像有人探討後認為︰『差異』在『關鍵處』!也在『對的人』!!於是『問題』變成了是否『相信』了『對的人』,且在『事物』之『關鍵處』着力,就『這樣』……『決定』了……是否從此以後都能過著『自主判斷』的日子的了!!!

220px-Louvre_identifiers_Ma1274-MR242

羅浮宮雕塑背後的標識符

一個『標識符』 ID identifier

能有多少好說之事,需要如是的陣仗?假使你已發現『身份證』比『你自己』更能『證明』你是誰!各種『號碼』效用之大,可以『轉帳購物』,你才剛知道『不變』 Immutable 之『物件』 object 要比『可變』 mutable 的『你』更『安全』『可靠』的哩!!不要『懷疑』,即使那些『號碼』因『你』而『有』,在『電腦語言』裡,他們可是『第一類公民』 First-class value ,享有第一等的『價值』??

雖然有時令人『千迴百轉』的想不通?是『機器』服務於『』,還是『』符合『機器』的『處理』?!

或許那個『鄭三絕』能讓人們『回回神』的吧!『鄭板橋』固因『詩書畫』稱『三絕』,他傳聞軼事『也絕』︰

『絕對』難能卻『對』,
『絕句』自可斷『句』,
『絕情』反倒多『情』。

鄭板橋‧竹

竹本【笨】虛心是我師

 

鄭板橋‧【一聯千金

龍虎山中真宰相

麒麟閣上活神仙

 

難得糊塗

難得糊塗

 

鄭縣令‧【崇仁‧大悲】寺‧庵之戀

硃筆一批

一半葫蘆一半瓢,合來一處好成桃;
徒令人定風歸寂,此後敲門月影遙:
鳥性悅時空即色,蓮花落處靜偏嬌;
是誰勾卻風流案,記取當年鄭板橋。

─── 《W!o 的派生‧十日談之《六》

 

想要了解派生『裝飾子』者,單靠文法定義是不足的︰

The current syntax for function decorators as implemented in Python 2.4a2 is:

@dec2
@dec1
def func(arg1, arg2, ...):
    pass

This is equivalent to:

def func(arg1, arg2, ...):
    pass
func = dec2(dec1(func))

without the intermediate assignment to the variable func. The decorators are near the function declaration. The @ sign makes it clear that something new is going on here.

 

首要清楚知道『函數』是什麼?

比方說《潜入派生》 Dive into Python 第二章第四節

《 2.4. Everything Is an Object 》講︰

2.4.2. What’s an Object?

Everything in Python is an object, and almost everything has attributes and methods. All functions have a built-in attribute __doc__, which returns the doc string defined in the function’s source code. The sys module is an object which has (among other things) an attribute called path. And so forth.

Still, this begs the question. What is an object? Different programming languages define “object” in different ways. In some, it means that all objects must have attributes and methods; in others, it means that all objects are subclassable. In Python, the definition is looser; some objects have neither attributes nor methods (more on this in Chapter 3), and not all objects are subclassable (more on this in Chapter 5). But everything is an object in the sense that it can be assigned to a variable or passed as an argument to a function (more in this in Chapter 4).

This is so important that I’m going to repeat it in case you missed it the first few times: everything in Python is an object. Strings are objects. Lists are objects. Functions are objects. Even modules are objects.

那麼我們將如何理解『在派生中,一切皆是物件。』這句話呢?要是不深入『派生』的『語法』以及『語意』,只依靠著『語用』根本是不足以『回答』的吧!而且不同的『程式語言』,『口號』不同,『哲學』也不一樣!!Python 號稱『多典範』,『程序』為主的寫作、『物件』中心之編程,『泛函式』概念的淺嚐,……等等,也許可以這麼說︰

『派生』支持的『作法』,讓它『語法』上『方便容易』。

『派生』不支持的『行事』,也可『己選自擇』的『表現』。

因此想要掌握 Python 語言,『深思』、『細慮』以及『多實驗』或許是個好的起步。就像嘗試看看,在『派生』中,什麼是『函式』 function 的呢?

pi@raspberrypi ~ $ python3
Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.

# 列出『整數』物件有的『屬性』與『方法』
>>> dir(3)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']


# 『泛函式』小試
>>> def 求值(函數,參數):
...     return 函數(參數)
... 

# 『函數』定義
>>> def f(x):
...     return x*x +2*x -1
... 

# 『函數』求值
>>> 求值(f,5)
34

# f 是『函數』物件的『標識符』
>>> f
<function f at 0x76a5cf60>

# 『函數』呼叫,是由『標識符』 f 與『參數元組』 (5) 所構成
>>> f (5)
34

# 『函數』的重要『屬性』是『可呼叫』 callable
>>> callable(f)
True

# 列出『函數』物件有的『屬性』與『方法』
>>> dir(f)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

# λ 『匿名函數』
>>> 求值(lambda x:x*x + 2*x -1,5)
34

>>> lambda x:x*x + 2*x -1
<function <lambda> at 0x76a5ced0>

>>> dir(lambda x:x*x + 2*x -1)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

 

─── 豈是一句『可呼叫』 callable 了得!! ───

─── 摘自《W!o 的派生‧十日談之《七》

 

同時深入『嵌套函數』內蘊︰

PEP 227 — Statically Nested Scopes

Abstract

This PEP describes the addition of statically nested scoping (lexical scoping) for Python 2.2, and as a source level option for python 2.1. In addition, Python 2.1 will issue warnings about constructs whose meaning may change when this feature is enabled.

The old language definition (2.0 and before) defines exactly three namespaces that are used to resolve names — the local, global, and built-in namespaces. The addition of nested scopes allows resolution of unbound local names in enclosing functions’ namespaces.

The most visible consequence of this change is that lambdas (and other nested functions) can reference variables defined in the surrounding namespace. Currently, lambdas must often use default arguments to explicitly creating bindings in the lambda’s namespace.

……

XXX Alex Martelli suggests comparison with Java, which does not allow name bindings to hide earlier bindings.

Examples

A few examples are included to illustrate the way the rules work.

XXX Explain the examples

>>> def make_adder(base):
...     def adder(x):
...         return base + x
...     return adder
>>> add5 = make_adder(5)
>>> add5(6)
11

>>> def make_fact():
...     def fact(n):
...         if n == 1:
...             return 1L
...         else:
...             return n * fact(n - 1)
...     return fact
>>> fact = make_fact()
>>> fact(7)
5040L

>>> def make_wrapper(obj):
...     class Wrapper:
...         def __getattr__(self, attr):
...             if attr[0] != '_':
...                 return getattr(obj, attr)
...             else:
...                 raise AttributeError, attr
...     return Wrapper()
>>> class Test:
...     public = 2
...     _private = 3
>>> w = make_wrapper(Test())
>>> w.public
2
>>> w._private
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: _private

 

An example from Tim Peters demonstrates the potential pitfalls of nested scopes in the absence of declarations:

i = 6
def f(x):
    def g():
        print i
    # ...
    # skip to the next page
    # ...
    for i in x:  # ah, i *is* local to f, so this is what g sees
        pass
    g()

 

The call to g() will refer to the variable i bound in f() by the for loop. If g() is called before the loop is executed, a NameError will be raised.

………

 

自能體會『第一類公民』之差異︰

閉包 (電腦科學)

電腦科學中,閉包英語:Closure),又稱詞法閉包Lexical Closure)或函式閉包function closures),是參照了自由變數的函式。這個被參照的自由變數將和這個函式一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函式和與其相關的參照環境組合而成的實體。閉包在執行時可以有多個例項,不同的參照環境和相同的函式組合可以產生不同的例項。

閉包的概念出現於60年代,最早實現閉包的程式語言是Scheme。之後,閉包被廣泛使用於函數語言程式設計語言如ML語言LISP。很多命令式程式語言也開始支援閉包。

在一些語言中,在函式中可以(巢狀)定義另一個函式時,如果內部的函式參照了外部的函式的變數,則可能產生閉包。執行時,一旦外部的 函式被執行,一個閉包就形成了,閉包中包含了內部函式的代碼,以及所需外部函式中的變數的參照。其中所參照的變數稱作上值(upvalue)。

閉包一詞經常和匿名函式混淆。這可能是因為兩者經常同時使用,但是它們是不同的概念。

……

Closures

In programming languages, closures (also lexical closures or function closures) are techniques for implementing lexically scoped name binding in languages with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment:[1] a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.[b] A closure—unlike a plain function—allows the function to access those captured variables through the closure’s copies of their values or references, even when the function is invoked outside their scope.

Example. The following program fragment defines a higher-order function startAt with a parameter x and a nested function incrementBy. The nested function incrementBy has access to x, because incrementBy is in the lexical scope of x, even though x is not local to incrementBy. The function startAt returns a closure containing a copy of the value of x or a copy of the reference to x from this invocation of startAt, and the function incrementBy, which adds the value of y to the value of x:

function startAt(x)
   function incrementBy(y)
       return x + y
   return incrementBy

variable closure1 = startAt(1)
variable closure2 = startAt(5)

Note that, as startAt returns a function, the variables closure1 and closure2 are of function type. Invoking closure1(3) (Meaning y=3) will return 4, while invoking closure2(3) (Meaning y=3) will return 8. While closure1 and closure2 refer to the same function incrementBy, the associated environments differ, and invoking the closures will bind the name x to two distinct variables with different values in the two invocations, thus evaluating the function to different results.

───