>ç±æ¯æä¹
å¿èï¼åææ©æ
ï¼ç±æ¯ä¸å«å¦ï¼ç±æ¯ä¸èªå¤¸ï¼ä¸å¼ çï¼ä¸ä½å®³ç¾çäºï¼ä¸æ±èªå·±ççå¤ï¼ä¸è½»æåæï¼ä¸è®¡ç®äººçæ¶ï¼ä¸å欢ä¸ä¹ï¼åªå欢ççï¼å¡äºå
容ï¼å¡äºç¸ä¿¡ï¼å¡äºç¼æï¼å¡äºå¿èã(1 CORINTHIANS 13:4-7)
#夿åå°è£
â夿âåâå°è£
âæ¯OOPçéè¦ç¹å¾ââåé¢è¯´çâç»§æ¿â乿¯ã使¯ï¼å¯¹äºPythonèè¨ï¼å¯¹è¿ä¸¤ä¸ªççè§£ä¹æå¾å¤ä¸åã建议读è
âåç¾å®¶å®´âï¼å°ç½ä¸æä¸ææå
³è¯é¢ï¼ä¸å°äººåäºæç« æ¥è®¨è®ºã
##夿
è¿éæä»
ä»
é对åå¦è
ï¼æç
§èªå·±ççè§£ï¼è°è°é¶åºç¡å¦Pythonç读è
å¯ä»¥ææ ·çè§£â夿âï¼å 为â夿âå°±å¦åå
¶åå䏿 ·ï¼å¨çè§£ä¸ä¹æ¯â夿âçã
å
æ¥çè¿æ ·çä¾åï¼
>>> "This is a book".count("s")
2
>>> [1,2,4,3,5,3].count(3)
2
ä¸é¢ç`count()`çä½ç¨æ¯æ°ä¸æ°æä¸ªå
ç´ å¨å¯¹è±¡ä¸åºç°ç次æ°ãä»ä¾åä¸å¯ä»¥çåºï¼æä»¬å¹¶æ²¡æéå®`count()`çåæ°ç±»åã类似çä¾åè¿æï¼
>>> f = lambda x,y:x+y
è¿è®°å¾è¿ä¸ª`lambda`彿°åï¼å¦æå¿è®°äºï¼è¯·å¤ä¹ [彿°(5)](./237.md)ä¸å¯¹æ¤çè§£éã
>>> f(2,3)
5
>>> f("qiw","sir")
'qiwsir'
>>> f(["python","java"],["c++","lisp"])
['python', 'java', 'c++', 'lisp']
è¿éæä»¬æ²¡æéå¶åæ°çç±»åï¼ä¹ä¸å®ä¸è½éå¶ï¼å ä¸ºå¦æéå¶äºï¼å°±ä¸æ¯pythonicäºãå¨ä½¿ç¨çæ¶åï¼å¯ä»¥ç»åæ°ä»»æç±»åï¼é½è½å¾å°ä¸æ¥éçç»æã
以ä¸ï¼å°±ä½ç°äºâ夿âââåä¸ç§è¡ä¸ºå
·æä¸å表ç°å½¢å¼åå½¢æçè½åï¼æ¢ä¸ç§è¯´æ³ï¼å°±æ¯å¯¹è±¡å¤ç§è¡¨ç°å½¢å¼çä½ç°ã
å½ç¶ï¼ä¹æäººå°±æ¤æåºäºå对æè§ï¼å 为æ¬è´¨ä¸æ¯å¨åæ°ä¼ å
¥å¼ä¹åï¼Python并没æç¡®å®åæ°çç±»åï¼åªè½è®©æ°æ®è¿å
¥å½æ°ä¹ååå¤çï¼è½å¤çåç½¢ï¼ä¸è½å¤çå°±æ¥éãä¾å¦ï¼
>>> f("qiw", 2)
Traceback (most recent call last):
File "", line 1, in
File "", line 1, in
TypeError: cannot concatenate 'str' and 'int' objects
æ¬ä¹¦ç±äºä¸å±äºè¿ç§æ¦å¿µäºè®ºèç´ï¼æä»¥ä¸è¿è¡è¿æ¹é¢çæ·±å
¥æ¢ç´¢ï¼ä»
ä»
æ¯åè¯åä½è¯»è
ç¸å
³ä¿¡æ¯ãå¹¶ä¸ï¼ä¹æ¯æç
§â人äºäº¦äºâçååï¼æ¢ç¶å¤§å¤æ°ç¨åºåé½å¨è®¨è®ºå¤æï¼é£ä¹æä»¬å°±æç
§å¤§å¤æ°äººè¯´çå»ä»ç»ï¼å°½ç®¡ææ¶åççææ¡å¨å°æ°äººæä¸ï¼ã
â夿âï¼è±ææ¯:Polymorphismï¼å¨å°æ¹¾è¢«ç§°ä½âå¤åâãç»´åºç¾ç§ä¸å¯¹æ¤æè¯¦ç»è§£é说æã
>å¤åï¼è±è¯ï¼Polymorphismï¼ï¼æ¯æç©ä»¶å°åç¨å¼å·è¡æï¼ç¸åçè¨æ¯å¯è½æé給å¤åä¸åçé¡å¥ä¹ç©ä»¶ï¼è系統å¯ä¾æç©ä»¶æå±¬é¡å¥ï¼å¼ç¼å°æé¡å¥çæ¹æ³ï¼èæä¸åçè¡çºãç°¡å®ä¾èªªï¼æè¬å¤åææç¸åçè¨æ¯çµ¦äºä¸åçç©ä»¶æå¼ç¼ä¸åçåä½ç¨±ä¹ã
åç®åç说æ³å°±æ¯âæå¤ç§å½¢å¼âï¼å°±ç®ä¸ç¥éåéï¼åæ°ï¼æå¼ç¨ç对象类åï¼ä¹ä¸æ ·è½è¿è¡æä½ï¼æ¥è
ä¸æãæ¯å¦ä¸é¢æ¾ç¤ºçä¾åãå¨Pythonä¸ï¼æ´ä¸ºpythonicçåæ³æ¯æ ¹æ¬å°±ä¸è¿è¡ç±»åæ£éªã
ä¾å¦èåç`repr()`彿°ï¼å®è½å¤é对è¾å
¥çä»»ä½å¯¹è±¡è¿åä¸ä¸ªå符串ãè¿å°±æ¯å¤æç代表ä¹ä¸ã
>>> repr([1,2,3])
'[1, 2, 3]'
>>> repr(1)
'1'
>>> repr({"lang":"python"})
"{'lang': 'python'}"
使ç¨å®åä¸ä¸ªå°å½æ°ï¼è¿æ¯ä½ä¸ºå¤æä»£è¡¨çã
>>> def length(x):
... print "The length of", repr(x), "is", len(x)
...
>>> length("how are you")
The length of 'how are you' is 11
>>> length([1,2,3])
The length of [1, 2, 3] is 3
>>> length({"lang":"python","book":"itdiffer.com"})
The length of {'lang': 'python', 'book': 'itdiffer.com'} is 2
ä¸è¿ï¼å¤æä¹ä¸æ¯ä¸è½çï¼å¦æè¿æ ·åï¼
>>> length(7)
The length of 7 is
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in length
TypeError: object of type 'int' has no len()
æ¥éäºãçé误æç¤ºï¼æç¡®åè¯äºæä»¬`object of type 'int' has no len()`ã
ä¸è¿°çç§ç§å¤æè¡¨ç°ï¼çå 为Pythonæ¯ä¸ç§è§£éåçè¯è¨ï¼ä¸éè¦è¿è¡é¢ç¼è¯ï¼åªå¨è¿è¡æ¶æç¡®å®ç¶æãæä»¥ï¼Pythonå°±è¢«è®¤ä¸ºå¤©çæ¯ä¸ç§å¤æçè¯è¨ãä¹æäººæç¸åè§ç¹ï¼è®¤ä¸ºPython䏿¯æå¤æï¼å¨çç±ä¸ï¼ä¹ç¨äºä¸è¿°å
容ãçæ¥ï¼ççåæ¯æ°´ï¼çç¡®è½å¤æä¸åçç»è®ºâââè¿æåæ¯æ°´å¢ï¼âåâè¿å©åæ¯æ°´äºï¼âã
äºè®ºï¼è®©ç»ææ³è
ãæä»¬ï¼å´è§ã
为äºè®©è¯»è
è½å¤è¿ä¸æ¥çè§£Pythonç夿ç¹ç¹ï¼å¿
é¡»è¦æ¯è¾ï¼ä¸è·ä¸çä¸ä¸åä¹äºå°å¤äºæ°´æ·±ç«ççå³è¦å¤§ä¼æ¯è¾ï¼æè½ä½ä¼å°èªå·±çæ´»å¨å¹¸ç¦çç¥å½å¤§è±åå
ã
ãThinking in Javaãçä½è
Bruce Eckelå¨2003å¹´5æ2æ¥å表äºä¸ç¯é¢ä¸º[ãStrong Typing vs. Strong Testingã](https://docs.google.com/document/d/1aXs1tpwzPjW9MdsG5dI7clNFyYayFBkcXwRDo-qvbIk/preview)çå客ï¼å¨å
¶ä¸å°JavaåPythonç夿ç¹å¾è¿è¡äºæ¯è¾ï¼å¨æ¤æéæé¨åå
容ï¼é温大å¸ç论述ã
å
æ¥æ¬£èµå¤§å¸ææ°åç䏿®µJava代ç ï¼
// Speaking pets in Java:
interface Pet {
void speak();
}
class Cat implements Pet {
public void speak() { System.out.println("meow!"); }
}
class Dog implements Pet {
public void speak() { System.out.println("woof!"); }
}
public class PetSpeak {
static void command(Pet p) { p.speak(); }
public static void main(String[] args) {
Pet[] pets = { new Cat(), new Dog() };
for(int i = 0; i < pets.length; i++)
command(pets[i]);
}
}
å¦æè¯»è
没æå¦ä¹ è¿Javaï¼å¯¹ä¸è¿°ä»£ç çè§£å¯è½ä¸æ¯å¾é¡ºç
ï¼è¿ä¸éè¦ã主è¦è§å¯`command(Pet p)`ï¼è¿ç§åæ³æå³ç彿°`command()`æè½æ¥åçåæ°çç±»åå¿
é¡»æ¯`Pet`ç±»åï¼å
¶å®ç±»åä¸è¡ãæä»¥ï¼å¿
é¡»å建`interface Pet`è¿ä¸ªæ¥å£å¹¶ä¸ç±»CatåDogç»§æ¿å®ï¼ç¶åæè½upcast them to the generic command() methodãï¼åæï¼ I must create a hierarchy of Pet, and inherit Dog and Cat so that I can upcast them to the generic command() method.ï¼
ä¸ä¸é¢ç代ç ç¸å¯¹åºï¼å¤§å¸æä¾äºPython代ç ï¼å¦ä¸æç¤ºï¼
# Speaking pets in Python:
class Pet:
def speak(self): pass
class Cat(Pet):
def speak(self):
print "meow!"
class Dog(Pet):
def speak(self):
print "woof!"
def command(pet):
pet.speak()
pets = [ Cat(), Dog() ]
for pet in pets:
command(pet)
注æè¿æ®µPython代ç ä¸ç`command()`彿°ï¼å
¶åæ°`pet`并没æè¦æ±å¿
é¡»æ¯åé¢ç`Pet`ç±»åï¼æ³¨æåºå大å°åï¼ï¼ä»
ä»
æ¯ä¸ä¸ªåå为`pet`ç对象å¼ç¨ç½¢äºãPythonä¸å
³å¿å¼ç¨ç对象æ¯ä»ä¹ç±»åï¼åªè¦æ¹å¯¹è±¡æ`speak()`æ¹æ³å³å¯ãæé读è
注æçæ¯ï¼å 为åå²åå ï¼2003å¹´ï¼ï¼å¤§å¸å½æ¶åçæ¯æ§å¼ç±»ã
æ ¹æ®æä»¬å¯¹Pythonççè§£ï¼ä¸é¢ä»£ç ä¸çç±»`Pet`å
¶å®æ¯å¤ä½çãæ¯çï¼å¤§å¸ä¹è¿ä¹è®¤ä¸ºï¼åªæ¯å 为大å¸å½æ¶æ¯å®å
¨æ¨¡ä»¿Javaç¨åºèåçãéåï¼å¤§å¸å°±ä¿®æ¹äºä¸é¢ç代ç ã
# Speaking pets in Python, but without base classes:
class Cat:
def speak(self):
print "meow!"
class Dog:
def speak(self):
print "woof!"
class Bob:
def bow(self):
print "thank you, thank you!"
def speak(self):
print "hello, welcome to the neighborhood!"
def drive(self):
print "beep, beep!"
def command(pet):
pet.speak()
pets = [ Cat(), Dog(), Bob() ]
for pet in pets:
command(pet)
ä¸ä»
å»æäºæ²¡ä»ä¹ç¨çç±»`Pet`ï¼åå¢å äºä¸ä¸ªæ°çç±»`Bob`ï¼è¿ä¸ªç±»æ ¹æ¬ä¸æ¯å¦`Cat`å`Dog`飿 ·çç±»åï¼åªæ¯å®ç¢°å·§ä¹æä¸ä¸ªåå为`speak()`çæ¹æ³ç½¢äºã使¯ï¼ä¹ä¾ç¶è½å¤å¨`command()`彿°ä¸è¢«è°ç¨ã
è¿å°±æ¯Pythonä¸ç夿ç¹ç¹ï¼å¤§å¸Brue Eckeléè¿é常æè¯´æäºç代ç 说æäºJavaåPythonçåºå«ï¼å¹¶å
åå±ç¤ºäºPythonä¸ç夿ç¹å¾ã
è¯å¦åé¢æè¿°ï¼Python䏿£æ¥ä¼ å
¥å¯¹è±¡çç±»åï¼ä¸é¢å¤§å¸æåç代ç ä¸é常æ¸
æ°è¡¨æäºè¿ç¹ï¼ï¼è¿ç§æ¹å¼è¢«ç§°ä¹ä¸ºâéå¼ç±»åâï¼laten typingï¼æè
âç»æå¼ç±»åâï¼structural typingï¼ï¼ä¹è¢«éä¿ç称为âé¸åç±»åâ(duck typeing)ï¼å
¶å«ä¹å¨ç»´åºç¾ç§ä¸è¢«è¡¨è¿°ä¸ºï¼
>å¨ç¨åºè®¾è®¡ä¸ï¼é¸åç±»åï¼è±è¯ï¼duck typingï¼æ¯å¨æç±»åçä¸ç§é£æ ¼ãå¨è¿ç§é£æ ¼ä¸ï¼ä¸ä¸ªå¯¹è±¡ææçè¯ä¹ï¼ä¸æ¯ç±ç»§æ¿èªç¹å®çç±»æå®ç°ç¹å®çæ¥å£ï¼èæ¯ç±å½åæ¹æ³å屿§çéåå³å®ãè¿ä¸ªæ¦å¿µçå忥æºäºç±James Whitcomb Rileyæåºçé¸åæµè¯ï¼âé¸åæµè¯âå¯ä»¥è¿æ ·è¡¨è¿°ï¼âå½çå°ä¸åªé¸èµ°èµ·æ¥åé¸åãæ¸¸æ³³èµ·æ¥åé¸åãå«èµ·æ¥ä¹åé¸åï¼é£ä¹è¿åªé¸å°±å¯ä»¥è¢«ç§°ä¸ºé¸åãâ
é¸åç±»åå°±æå³çå¯ä»¥åä»»ä½å¯¹è±¡åé任使¶æ¯ï¼è¯è¨åªå
³å¿è¯¥å¯¹è±¡è½å¦æ¥åè¯¥æ¶æ¯ï¼ä¸å¼ºæ±è¯¥å¯¹è±¡æ¯å¦æä¸ç§ç¹å®çç±»åââ该对象çå¤æè¡¨ç°ã
对äºPythonçè¿ç§ç¹å¾ï¼æä¸æ¹ç¨åºå䏿¥åï¼ä»ä»¬è®¤ä¸ºå¨ç¨åºè¢«æ§è¡çæ¶åï¼å¯è½æ¶å°é误ç对象ï¼èä¸è¿ç§é误è¿å¯è½æ½ä¼å¨ç¨åºçæä¸ªè§è½ãå æ¤å¨ç¼ç¨é¢åå°±æäºâ强类åâï¼å¦Javaï¼åâ弱类åâï¼å¦Pythonï¼ä¹äºã
å¯¹äºæ¤ç±»äºè®ºï¼å¤§å¸Brue Eckelå¨ä¸é¢ææå°çå客ä¸ï¼ç»åºäºé常æç¡®çåçãä¸é¢åææå½äºæ¤ï¼
>Strong testing, not strong typing.
>So this, I assert, is an aspect of why Python works. C++ tests happen at compile time (with a few minor special cases). Some Java tests happen at compile time (syntax checking), and some happen at run time (array-bounds checking, for example). Most Python tests happen at runtime rather than at compile time, but they do happen, and that's the important thing (not when). And because I can get a Python program up and running in far less time than it takes you to write the equivalent C++/Java/C# program, I can start running the real tests sooner: unit tests, tests of my hypothesis, tests of alternate approaches, etc. And if a Python program has adequate unit tests, it can be as robust as a C++, Java or C# program with adequate unit tests (although the tests in Python will be faster to write).
读大å¸çè¯ï¼ééçé¡¶ï¼è±ç¶å¼æï¼åä¹ä¸å»åä¸é£äºæµªè´¹å¾æ²«çäºè®ºäºã
顺便ååè¯è¯»è
ï¼ä»å表äº2003å¹´5æ2æ¥ç[ãStrong Typing vs. Strong Testingã](https://docs.google.com/document/d/1aXs1tpwzPjW9MdsG5dI7clNFyYayFBkcXwRDo-qvbIk/preview)ä¸å¯ä»¥çåºï¼å¤§å¸å¨é£æ¶å·²ç»å¼å§å¨æè¯¾çè¿ç¨ä¸ç»å¦ç使ç¨Pythonäºã2003å¹´ï¼é£æ¶åèµµå½ç¨åºåï¼æå¤å°ç¥éè¿ä¸ªæç䏿ä¸ç§å为Pythonçè®¡ç®æºé«çº§è¯è¨ã
对äºå¤æé®é¢ï¼æåè¿è¦å诫读è
ï¼ç±»åæ£æ¥æ¯æ¯æå¤æçå©å¨ï¼æ¯å¦typeãisinstance以åisubclass彿°ï¼æä»¥ï¼ä¸å®è¦æ
ç¨è¿äºç±»åæ£æ¥å½æ°ã
##å°è£
åç§æå
âå°è£
âï¼æ¯ä¸æ¯æä»£ç åå°æä¸ªä¸è¥¿éé¢ï¼â人âå¨ç¼è¾å¨ä¸æå¼ï¼å°±çä¸å°äºå¢ï¼
é¤éæ¯ä½ çæ¾ç¤ºå¨åäºã
å¨ç¨åºè®¾è®¡ä¸ï¼å°è£
(Encapsulation)æ¯å¯¹å
·ä½å¯¹è±¡çä¸ç§æ½è±¡ï¼å³å°æäºé¨åéèèµ·æ¥ï¼å¨ç¨åºå¤é¨çä¸å°ï¼å³æ æ³è°ç¨ï¼ä¸æ¯äººç¨ç¼ççä¸å°é£ä¸ªä»£ç ï¼é¤éç¨æç§å 坿è
æ··æ·æ¹æ³ï¼é æç°å®ä¸çå°é¾ï¼ä½è¿ä¸æ¯å°è£
ï¼ã
è¦äºè§£å°è£
ï¼ç¦»ä¸å¼âç§æåâï¼å°±æ¯å°ç±»æè
彿°ä¸çæäºå±æ§éå¶å¨æä¸ªåºåä¹å
ï¼å¤é¨æ æ³è°ç¨ã
Pythonä¸ç§æåçæ¹æ³ä¹æ¯è¾ç®åï¼å°±æ¯å¨åå¤ç§æåç屿§ï¼å
æ¬æ¹æ³ãæ°æ®ï¼åååé¢å åä¸å线ãä¾å¦ï¼
#!/usr/bin/env python
# coding=utf-8
class ProtectMe(object): #Python 3: class ProtectMe:
def __init__(self):
self.me = "qiwsir"
self.__name = "kivi"
def __python(self):
print "I love Python." #Python 3: print("I love Python.")ï¼ä¸åï¼ä»ç¥
def code(self):
print "Which language do you like?"
self.__python()
if __name__ == "__main__":
p = ProtectMe()
print p.me
print p.__name
è¿è¡ä¸ä¸ï¼ççææï¼
$ python 21102.py
qiwsir
Traceback (most recent call last):
File "21102.py", line 21, in
print p.__name
AttributeError: 'ProtectMe' object has no attribute '__name'
æ¥çæ¥éä¿¡æ¯ï¼åè¯æä»¬æ²¡æ`__name`é£ä¸ªå±æ§ãæç¶éèäºï¼å¨ç±»çå¤é¢æ æ³è°ç¨ãåè¯è¯é£ä¸ªå½æ°ï¼å¯å¦ï¼
if __name__ == "__main__":
p = ProtectMe()
p.code()
p.__python()
ä¿®æ¹è¿é¨åå³å¯ãå
¶ä¸`p.code()`çæå¾æ¯è¦æå°åºä¸¤å¥è¯ï¼`"Which language do you like?"`å`"I love Python."`ï¼`code()`æ¹æ³å`__python()`æ¹æ³å¨åä¸ä¸ªç±»ä¸ï¼å¯ä»¥è°ç¨ä¹ãåé¢çé£ä¸ª`p.__python()`è¯å¾è°ç¨é£ä¸ªç§ææ¹æ³ãççææï¼
$ python 21102.py
Which language do you like?
I love Python.
Traceback (most recent call last):
File "21102.py", line 23, in
p.__python()
AttributeError: 'ProtectMe' object has no attribute '__python'
妿¿ä»¥å¿ã该è°ç¨çè°ç¨äºï¼è¯¥éèçéèäºã
ç¨ä¸é¢çæ¹æ³ï¼çç¡®åå°äºå°è£
ã使¯ï¼æå¦æè¦è°ç¨é£äºç§æå±æ§ï¼æä¹åï¼
å¯ä»¥ä½¿ç¨`property`彿°ã
#!/usr/bin/env python
# coding=utf-8
class ProtectMe(object): #Python 3: class ProtectMe:
def __init__(self):
self.me = "qiwsir"
self.__name = "kivi"
@property
def name(self):
return self.__name
if __name__ == "__main__":
p = ProtectMe()
print p.name #Python 3: print(p.name)
è¿è¡ç»æï¼
$ python 21102.py
kivi
ä»ä¸é¢å¯ä»¥çåºï¼ç¨äº`@property`ä¹åï¼å¨è°ç¨é£ä¸ªæ¹æ³çæ¶åï¼ç¨çæ¯`p.name`çå½¢å¼ï¼å°±å¥½åå¨è°ç¨ä¸ä¸ªå±æ§ä¸æ ·ï¼è·åé¢`p.me`çæ ¼å¼ç¸åã
çæ¥ï¼å°è£
çç¡®ä¸æ¯è®©â人çä¸è§âã
------
[æ»ç®å½](./index.md) | [ä¸èï¼ç±»(5)](./209.md) | [ä¸èï¼å®å¶ç±»](./239.md)
å¦æä½ è®¤ä¸ºæå¿
è¦æèµæï¼è¯·éè¿æ¯ä»å®ï¼**[email protected]**,ä¸èææ¿ã