面向对象编程

id(1) # 1 是一个数据对象
type(1)
dir(1)[:5] # c查看属性和方法

id("a")
type("a")
dir("a")[:5]

abs(-1) # 函数也是对象
type(abs)
dir(abs)[:5]

"abc".upper()

(1+2j).real
(1+2j).imag

类的定义与调用

class <name>:
    def __init__(self,<args>):
    def <name>(self,<args>)
class Force:
    def __init__(self, x, y):
        self.fx, self.fy = x, y 
        
    def show(self):
        print("Force<%s, %s>" % (self.fx, self.fy))
    
    def add(self, force2): # 与另一个力合力
        x = self.fx + force2.fx
        y = self.fy + force2.fy
        return Force(x, y)

f1 = Force(0,1)
f1.show()

f2 = Force(3,4)
f3 = f1.add(f2)
f3.show()
            

Force<0, 1>
Force<3, 5>

类定义中中的特殊方法

  1. __add__(self,other) -> +
  2. __sub__(self,other) -> -
  3. __mul__(self,other) -> *
  4. __div__(self,other) -> /
  5. __radd__(self,other) 自己作为右操作符
  6. __eq__(self,other) -> == equal
  7. __ne__(self,other) -> != not equal
  8. __lt__(self,other) -> < less than
  9. __gt__(self,other) -> > greater than
  10. __le__(self,other) -> <= less than and equal
  11. __ge__(self,other) -> >=
from os.path import join
class FileObject:
    def __init__(self, filepath="/root/linux_tutorial", filename="smaple.tmp"):
        print("open file!")
        self.file = open(join(filepath,filename),"w")
    
    def __del__(self):
        print("close file!")
        self.file.close()
        del self.file
            
file1 = FileObject()
del file1        

open file!
close file!

class Force:
    def __init__(self, x, y):
        self.fx, self.fy = x, y 
        
    def show(self):
        print("Force<%s, %s>" % (self.fx, self.fy))
    
    def add(self, force2): # 与另一个力合力
        x = self.fx + force2.fx
        y = self.fy + force2.fy
        return Force(x, y)
    
    __add__ = add
    
    def __str__(self):
            return "Force<%s, %s>" % (self.fx, self.fy)
    def __eq__(self,force2):
        return (self.fx == force2.fx) and (self.fy == force2.fy)
    
f1 = Force(0,1)
f1.show()

f2 = Force(3,4)
#f3 = f1.add(f2)
f3 = f1 + f2
#f3.show()
print(f3)           
print("%s==%s -> %s" % (f1,f2,f1==f2))

Force<0, 1>
Force<3, 5>
Force<0, 1>==Force<3, 4> -> False

自定义对象排序

  1. __lt__
num = [5,3,4,6,2]
num.sort(reverse=True)
num

sorted(num) # 返回排序的副本,不改变原来列表

class Student:
        def __init__(self, name, grade):
            self.name, self.grade = name,grade
        def __lt__(self,other):
            return self.grade < other.grade
        def __str__(self):
                return "(%s,%s)" % (self.name, self.grade)
        __repr__ = __str__
        
s = list()
s.append(Student("zs",12))
s.append(Student("li",7))
s.append(Student("ww",16))
s.append(Student("wk",15))

s.sort(reverse = True)

print(s)

sorted(s)

[(ww,16), (wk,15), (zs,12), (li,7)]

[(li,7), (zs,12), (wk,15), (ww,16)]

类的继承

class <child_name> (<father_name>)
    def <override>)(self,...)
  1. override的子类调研父类methodsuper().Method_name()
  2. self 代表对象实例
<object>.<method>(<args>)
<class>.<method>(<object>,<args>)
class Car:
    def __init__(self,name):
        self.name = name
        self.remain_mile = 0
    def fill_fuel(self,miles):
        self.remain_mile = miles
    def run(self,miles):
        print(self.name,end=":")
        if self.remain_mile >= miles:
            self.remain_mile -= miles
            print("run %d miles!" % (miles))
        else:
            print("fuel out!")
class GasCar(Car):
    def __init__(self,name,capacity):
        super().__init__(name)
        self.capaciry = capacity
    def fill_fuel(self,gas): # 加汽油gas升]
        self.remain_mile = gas * 6.0 # 每升考6公里
class ElecCar(Car):
    def fill_fuel(self,power): # 充电power度
        self.remain_mile = power * 3.0 # 每度电3公里
        
gcar = GasCar("BMW",50)
gcar.fill_fuel(50.0)
gcar.run(200.0)
GasCar.run(gcar,100.0)

ecar = ElecCar("Tesla")
ecar.fill_fuel(60.0)
ecar.run(100.0)
ElecCar.run(ecar,100)


def test(arg):
    arg.run(60)

test(gcar)

BMW:run 200 miles!
BMW:run 100 miles!
Tesla:run 100 miles!
Tesla:fuel out!
BMW:fuel out!

a = GasCar("aaa",90)
type(a)
#print(GasCar.__doc__)
help(GasCar)

Help on class GasCar in module main:

class GasCar(Car)
| GasCar(name, capacity)
|
| Method resolution order:
| GasCar
| Car
| builtins.object
|
| Methods defined here:
|
| init(self, name, capacity)
| Initialize self. See help(type(self)) for accurate signature.
|
| fill_fuel(self, gas)
|
| ----------------------------------------------------------------------
| Methods inherited from Car:
|
| run(self, miles)
|
| ----------------------------------------------------------------------
| Data descriptors inherited from Car:
|
| dict
| dictionary for instance variables (if defined)
|
| weakref
| list of weak references to the object (if defined)

例外处理

  1. try-expect
try:
    <do something>
expect <error type> [as e]:
    <deal>
  1. try-finally
try:
    <do something>
expect <error type> [as e]:
    <deal>
finally:
    <do something>
  1. try-else
try:
    <do something>
expect <error type> [as e]:
    <deal>
else:
    <no error do something>
try:
    1/0
except :
    pass
try:
    1/0
except ZeroDivisionError as e:
    print(e)
else:
    print("else")
finally:
    print("finally")

division by zero
finally

推导式

  1. list [<expression> for <var> in <iterable_obj> if <condition>]
  2. dict {<key expression> : <value experssion> for <var> in <iterable_obj> if <condition>}
  3. 生成器推导式 (<expression> for <var> in <iterable_obj> if <condition>])
    • 返回一个生成器对象,也是可以迭代的
    • 但生成器并不会立即产生全部元素,仅在要用到元素的时候才生产,可以极大节省内存
nums = [1,2,3,4,5,6]
print([x*2 for x in nums])
print([x*2 for x in range(10) if x%2==0])
print({"k%d"%(x,):x*2 for x in range(10)})
print({x*x for x in range(10)})
print({x+y for x in range(10) for y in range(x)})

[2, 4, 6, 8, 10, 12]
[0, 4, 8, 12, 16]
{'k0': 0, 'k1': 2, 'k2': 4, 'k3': 6, 'k4': 8, 'k5': 10, 'k6': 12, 'k7': 14, 'k8': 16, 'k9': 18}
{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}

agen1 =  [x*x for x in range(10)]
agen2 =  (x*x for x in range(10))
print(type(agen1))
print(type(agen2))
print(agen1)
print(agen2)
print(list(agen2))
for i in agen2:
    # print(i)
    pass
print(list(agen2))

<class 'list'>
<class 'generator'>
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object at 0x7f5758e48200>
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[]

生成器函数 generator

  1. 使用generator可以迭代庞大的序列,而且不需要在内存中存储整个序列
  2. 生成器函数与普通函数相同,只是将return换成yield
  3. yield与return区别
    • yield 立即返回一个值;下一次调用(下一次迭代)生成器函数时,从yield后面的语句执行,直到再次yield返回或终止
    • return 终止函数执行,下次调用重新执行函数
    • 可以运行独立的函数调用,函数可以暂停或挂起,并在需要的时候从离开的地方继续或重新开始
def even_number(max):
    n = 0
    while n < max:
        yield n
        n += 2
g1 = even_number(10)
for i in g1:
    print(i)
print(list(g1)) # 生成完成,在取不会有值    

0
2
4
6
8
[]

参考

https://docs.python.org/zh-cn/3/library/typing.html#module-typing