python笔记

https://www.jianshu.com/p/1e375fb40506

# -*- coding:utf-8 -*-
"""
@author:zhen.xiao
@file:index.py
@time:2018/5/1210:04
"""
'''
使用模块:  
注意:file必须得是含由__init__函数的文件夹或者是包(含由__init__)

from file import demo #调用模块语句
demo.Print()          #执行file包中的demo.py

print __file__      #输出文件路径
print __doc__       #输出文档注释
'''

'''
函数避免了做重复的事情,做一个模板:

def Print(name):
    print name,'在学习'

Print('肖震')
Print('小震')
'''

'''
函数式编程--返回值的使用,调用函数
注意自己的编程的习惯
函数之间上下代码间隔为2行,逗号','后面一定加一个空格

def login(username):
    if username == '肖震':
        return '登录成功'
        detail(username)
    else:
        return '登录失败'


def detail(username):
    print username, 'ssssssss'

if __name__ == '__main__':
    user = raw_input('请输入用户名:')
    res = login(user)
    if res == '登录成功':
        detail(user)
    else:
        print '失败失败'
    login(user)
'''

'''
函数的参数不定,就可以这么做  *arg:默认当个函数列表传进来,   **arg:字典
def show(*arg):
    for item in arg:
        print item
show('xiaozhen','xiao','xiaozhen','xiao','xiaozhen','xiao')
    
#传参数的时候可以根据标准的key=value去传,
#但是传参数的话就要把字典前面加上两个**
def show(**karg):
    for item in karg.items():
        print item
user_dict = {'k1': 123, 'k2': 456}
show(name='alex', age='24')

show(**user_dict)   #会遇到非常多的这种情况
'''

# 生成器
'''
print range(10)
print xrange(10)
# 创建xrange的时候,没有立马出来,说明现在还没有到内存中----迭代器类型
# 但是当你用for循环去迭代它的时候,就会得到0-9
# 每一次循环,创建一次,相当于延迟创建
for item in xrange(10):
    print item


# 生成器    延迟   可以在多线程的时候作为一个线程池
# 调用这个函数的时候你得到的什么也不是,这是一个生成器对象
# 生成器只有在你遍历的时候函数里面的代码才会执行,并且每一次循环只执行一条


def foo():    # generator object foo
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5
    yield 6

re = foo()
for item in re:
    print item

# 实例来练习生成器
def XiaoReadrLines():
    seek = 0
    while True:
        with open('D:/temp.txt', 'r') as f:
            f.seek(seek)  # seek()根据设置的字节,按照字节往下读,默认为0,从文件的开始往下读
            data = f.readline()
            if data:
                seek = f.tell()     # 获取上一次读取的位置,下次再接着上一次的位置执行
                yield data
            else:
                return  # return之后整个函数都不再执行了,注意与yield的区别
# print XiaoReadrLines()   这样执行的话就是一个生成器
# generator object XiaoReadrLines at 0x000000000383DB88

for item in XiaoReadrLines():
    print item
'''

'''
三元运算和lambda表达式
三元运算:
result = 'gt' if 1 > 3 else 'it'

(匿名函数)lambda表达式:匿名就是没有名字,只能调用一次(你的程序比较简单,并且不是经常会被调用,就可以写成lambda的形式)
a = lambda x,y:x+y
print a(4, 10)
而且lambda函数经常和  map()   一起使用:
            map(lambda x: x**x, range(10))


temp = lambda x, y: x+y  #x,y是参数,冒号:后面的内容就是对于参数的操作
print temp(4, 10)

'''

'''
内置函数
help() # 帮助
    a = []
    help(a)
dir()   key
vars()  key-value{}
type()
import temp
reload(temp) #python中模块只会导入一次,下一次用的时候不需要再去导入,如果还想导入,就用reload(temp)
id()
-----------------
print  cmp(2, 3)     -1
print cmp(2, 2)       0
print cmp(2, 1)       1
print cmp(10, 1)      1
print abs(-10)        10
print bool(-1)        False
print divmod(9,3) # 得到的结果是9除以3的商和余数             (3, 0)
print divmod(9, 2)                                          (4, 1)
print max([11,22,33,333])                                    333
print min([11,22,33,333])                                    11
print sum([11,22,33,333])                                    399
---------------------------------------------

print all([1, 2, 3, 0])  # 判断后面可迭代对象的布尔值,如果全部为真,就输出True             bool(0) = False
print all([1, 2, 3, 1])

print any([0, 0, 0, 0])  # 判断后面可迭代对象的布尔值,如果有一个为真,就输出True 全部为假,输出False
print any([1, 0, 0, 0])

# 通过上面的方式(all,any)就能判断列表里面有没有空的字符串
# 因为 bool('') 和 bool(None) = False

print chr(55)  # 数字对应的字符   动态生成数字,然后通过chr()就能动态生成字母,也就是动态验证码的原理
print chr(65)
print chr(66)

# 与chr相反的就是ord()  # 字母对应的数字
print ord('A')
print ord('B')

print hex(2)    # 十六进制
print oct(2)    # 八进制
print bin(2)    # 二进制
----------------------------------------------------
xiao = ['手表', '汽车', '房子']
for item in xiao:
    print item

for item in enumerate(xiao, 1):   # 表示序列是从下标1开始的,可以随意定义
    print item[0], item[1]
    print item
------------------------------------------------------
字符串的格式化:
format
s = 'i am {0},{1}'   # {0}和{1}表示占位符,想用的时候就往里面加参数
print s.format('alex', 'zhen')
------------------------------------------------------
print apply(Function, ('aaaaa'))        # 执行函数
--------------
map(Function, iterable)
map做了一件事,就是遍历了list,并且把list中的每一个数当做参数传入当Function中
比如:
xiao = [11, 22, 33]
temp = map(lambda x: x+100, xiao)
print temp
--------------
filter(Function, iterable)  #True序列
filter()做了一件事,就是对于list中的每一个元素传入Function中,当Function返回True的时候就留下,返回False的时候就过滤掉

xiao = [11, 22, 33]
def foo(arg):
    if arg <= 22:
        return True
    else:
        return False
temp = filter(foo,xiao)
print temp   # 结果[11, 22]
----------------
reduce()  #可以做累加累乘:下面例子,第一次计算1+2,得到的返回值3再与3相加,于是得到3+3 = 6
            同理做累乘,第一次计算1*2,计算结果为2,返回2的值再与3相乘,得到最后结果2*3 = 6
reduce区别于上面的map和filter是它必须有两个参数,一个参数的话就返回那一个数
print reduce(lambda x,y: x+y,[1, 2, 3])   >>>6
print reduce(lambda x,y: x*y,[1, 2, 3])   >>>6
print reduce(lambda x, y: x+y, [1])       >>>1
print reduce(lambda x, y: x*y, [1])       >>>1

上面四个内置函数的总结:
以上四个的表达形式都是相同的,就是函数的名称不同
0. apply是执行函数的
1. map是对所有的元素进行操作  
2. filter是进行过滤的,只有function的返回值为True的时候才会有操作   过滤嘛
3. reduce做累加累乘累除什么的
----------------------------------------------------------------------
zip():其实就是把传入的list的行变列,就是将每一行对应元素组成新的列,然后输出
x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
q = [10, 11, 12]
print zip(x, y, z, q)   >>>[(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]

如果元素少了怎么办?
x = [1, 2]
y = [4]
z = [7, 8, 9]
q = [10, 11, 12]
print zip(x, y, z, q)   >>>[(1, 4, 7, 10)]
缺了哪个列对应的元素,哪个列就不显示白
----------------------------------------------------------------------
***反射***装逼利器   以字符串的形式导入模块: __import__(model),并且以字符串的形式执行函数: getattr(model,func)

大型程序:设计模式:比如工厂模式,就必须用这个实现,就避免耦合

开胃小菜:
假如老板给了你一个excle表,里面的内容是这样的:
```````````````
hostname memory
主机A    8*8
主机B    16*8
````````````````
你从表中读出的数据是a = '8*8',string类型,老板想让你对里面的内容计算,怎么弄呢?
eval(a)
作用就是:  将你读入的string类型的文本当做对象去计算里面的内容
a = '8*8'  假设就是你在表格内读出的内容
print eval(a)   >>>64   #eval()函数将其计算出来
 
---反射来喽---
需求:给了你字符串,通过字符串导入模块
temp = 'sys'  # sys是一个模块,平时就是import os 就可以了,但是我想让你通过字符串的形式导入
也就是说给了你一个变量temp,不准用import sys,就把sys模块导入进来
temp = 'sys'
model = __import__(temp)
print model.path  # path是sys模块里面的方法,用于显示路径
# >>>['C:\\Users\\Mr.xiao\\PycharmProjects\\18day03\\main', 'C:\\Users\\Mr.xiao\\PycharmProjects\\18day03']等等

继续反射:
需求:
两个数据库模块,sql和sqlserver,两个模块内都有两个计算同样用户某样数据个数的函数count(),一个含有1条,一个含有2条,
之前都是使用
import sqlserverhelper
print sqlserverhelper.count()
现在down机了,要改数据库,需要下面形式进行改
import mysqlhelper
print mysqlhelper.count()
但是太麻烦了,还只是在mian函数里面改的
可以用           -----------反射(可以读string类型,通过字符串的形式导入模块,并且以字符串的形式执行函数)

# temp = 'mysqlhelper'
temp = 'sqlserverhelper'
model = __import__(temp)
print model.count   >>><function count at 0x0000000002A0C518>

下面就是以字符串的形式执行函数

temp = 'mysqlhelper'   模块(字符串形式)
func = 'count'         模块里面的函数(字符串形式)
model = __import__(temp)
Function = getattr(model, func)   # getattr就是去model这个模块中获取model中的函数,并且这个函数名是以字符串形式的
print Function   >>>function count at 0x0000000002E5C518>  这里怎么返回的是函数呐???版本?返回应该是1
------------------------------------------------
getattr() 获取模块中的某一个函数
hasattr() 判断某一个函数中有没有某一个函数
        module = __import__('sqlserverhelper')
        print dir(module)         >>>['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'count']
        val = hasattr(module, 'version')
        print val                 >>>False
delattr() 删除模块中的某一个函数   
---------------------------------------------------------
这些面向对象的时候才会用到,都是用于操作类的
isinstance()
issubclass()
super()
staticmethod()

--------------------------------------------------------------
-----------------------常用模块---------------------------------
---------------------------------------------------------------
import random          #random模块
# print random.random()   # 生成0-1之间任意的随机数   >>>0.876753108367 再执行一次:0.0521871726502 再执行一次:0.172469152628
print random.randint(1, 2)   # 生成范围之内的数字,而且是int型的,也就是只有1和2
print random.randint(1, 10)  # 生成范围之内的数字,而且是int型的,也就是只有1-10(包括1和10)之间的int数
                             # >>>6 7 3 5
# print random.randrange(1, 10)   # 生成的int型整数的范围变成 1<= x <10,左闭右开

如何随机生成字母:
import random
temp = random.randint(65, 90)
print chr(temp)

如何生成六位验证码,既包含数字又包含字母(做判断即可)
import random
code = []
for i in range(6):
    if i == random.randint(1, 5):
        code.append(str(random.randint(1, 5)))   # 注意,这里的数字和下面的字母类型不一样,转换成字符串的时候会有问题,str转一下
    else:
        temp = random.randint(65, 90)
        code.append(chr(temp))
print code
# >>> ['H', 'F', 'T', 'J', 'B', 'Y']
# >>> ['U', 'J', 5, 'Z', 'R', 'N']
# 字符需要格式化为字符串
print ''.join(code)
# VLSAZH
# IQ4DTY

或者:
import random
checkcode = ''
for i in range(4):
    current = random.randrange(0, 4)
    if current != i:
        temp = chr(random.randint(65, 90))
    else:
        temp = random.randint(0, 9)
    checkcode += str(temp)   +=是字符串的拼接,要使用''.join(),这样的效率要高,否则+=每一次都要在内存中开辟空间
print checkcode
# VIF3  EFD3
-------------------------------------------------------------------
md5加密:md5不能再反写,用户输入的值可以先加密,再和md5的值进行对比
import hashlib
hash = hashlib.md5()
hash.update('admin')
print hash.hexdigest()
# >>>21232f297a57a5a743894a0e4a801fc3,加密之后是16进制
print hash.digest()   # 和上面就是长度的区别
--------------------------------------------------------------------
序列化和json    以前web前后端都是xml,现在都被json取代了,同样的存储量,xml要比json大很多
                pickle是用在python程序之间,用的比较多
序列化pickle
json只能提供常规格式的序列化  可以直接看出来格式,pickle是不可读的

序列化之后python和pyhton代码之间进行文件传输,也可以说成内存共享
序列化就是用dumps()
反序列化就是用loads()进行
序列化list到文件:dump(list,open('')),就是将dumps的s去掉即可

import pickle
xiao = ['alex', 11, 22, 'ok', 'shuai']

dumpsed = pickle.dumps(xiao)
print dumpsed
print type(dumpsed)   

>>>
(lp0
S'alex'
p1
aI11
aI22
aS'ok'
p2
aS'shuai'
p3
a.   序列化的结果,不过就是看不懂
<type 'str'>

# 反序列化
loadsed = pickle.loads(dumpsed)   # 用loads()进行反序列化
print loadsed   # >>>['alex', 11, 22, 'ok', 'shuai']
print type(loadsed)   # 类型就是list型,和序列化之前是一样的

# 如何序列化到文件呢??

import pickle
xiao = ['alex', 11, 22, 'ok', 'shuai']
# pickle.dump(xiao, open('D:/temp.pk', 'w'))   # 把dumps改成dump就可以了,别忘了格式
result = pickle.load(open('D:/temp.pk', 'r'))
print result   # >>>['alex', 11, 22, 'ok', 'shuai']

pickle和json的对比:
import json
name = {'name': 'xiaozhen', 'age': 23}
result = json.dumps(name)
print result
print type(result)
# >>> {"age": 23, "name": "xiaozhen"}  <type 'str'>
import pickle
res = pickle.dumps(name)
print res
print type(res)
>>>
(dp0
S'age'
p1
I23
sS'name'
p2
S'xiaozhen'
p3
s.
<type 'str'>


import json
name = {'name': 'xiaozhen', 'age': 23}
result = json.dumps(name)
res = json.loads(result)
print res
# >>>{u'age': 23, u'name': u'xiaozhen'} 注意内存中默认形式是Unicode编码,所以加上了u开头了
-----------------------------------------------------------------------
re模块(正则表达式)
    re.match(parttern, string, flags)flags这个参数不用管,默认即可
6个函数可以解决问题
complie()
match() search() findall()
group() groups()

import re
# re.match(你写的表达式, 一大堆给你的字符串让你进行匹配)
# re.search()格式同上
res1 = re.match('\d+', '123asfroi21e413ij4u3')  # 注意哈,match只从开头开始找,找到(成功)就输出对象,找不到(失败)就输出None
print res1           # >>> <_sre.SRE_Match object at 0x000000000390E6B0>
res2 = re.search('\d+', 'asfroi21e413ij4u3')    # search是从整个字符串开始找,连续往下找,知道找到就返回objext
print res2           # >>>   <_sre.SRE_Match object at 0x000000000390E718>
print res1.group()   # >>> 123  使用group()
print res2.group()   # >>> 21
# 上面这俩,找不到的话都会返回None,None不是对象,就无法调用group函数,找到了就会返回对象,对象有group函数,就可以使用了

  
import  re
res3 = re.findall('\d+', '123asfroi21e413ij4u3')
print res3   # >>> ['123', '21', '413', '4', '3']
# 之前的match和search都只是拿出来一个,就是找到就返回第一个,但是findall将所有的都返回

compile()编译,编译之后再去找就快了很多

import re
com = re.compile('\d+')  # 编译一次,再去找99次,省了98次编译pattern,效率很高
print com.findall('123asfroi21e413ij4u3')   # >>>['123', '21', '413', '4', '3']
# 上面的match,search,findall都是按照上面的格式进行的,先进性编译pattern,再去字符串中找

import re
res4 = re.search('(\d+)', '123asf4321roi21e413ij4u3')   # 注意,这里的\d+被括号()括起来了
print res4.groups()   # >>> ('123',)   注意与下面的区别,groups只和正则表达式的分组有关,注意res4的正则表达式被()起来,说明分组了
print res4.group()    # >>> 123
res5 = re.search('(\d+)\w*(\d+)', '123asfr4321oi21e413ij4u3')
print res5.group()    # >>> 123asfr4321oi21e413ij4u3    group就是把所有满足正则表达式的东西全拿出来
print res5.groups()   # >>> ('123', '3')                groups就是只获取组里面的东西,注意(\d+),这就是一个正则表达式组

常用的正则表达式格式:
\d    : 数字
\w    :  数字,字母,下划线
\t    : 制表符
.     : 除了回车以外的所有字符 
  
*     : >= 0
+     :  >= 1
?     :  0 or 1
{m}   :  m次
{m, n}: 表示范围,出现m次和n次之间的次数,包括m和n
        import re
        res0 = re.search('a{3,5}', 'aaaaa')
        print res0.group()   # >>> aaaaa
'''
# 44mins21





# -*- coding:utf-8 -*-
"""
@author:Levy
@file:index.py
@time:2018/5/1315:23
"""
'''
-----------------------------反射----------------------------------------
# 需求:我们根据用户输入的url的不同,去返回给用户不同的界面

# 规范 xxx/xxx

# ************搬砖式:************
from backend import account
data = raw_input('请输入地址:')
# array = data.split('/')
if data == 'account/login':
    account.login()
elif data == 'account/logout':
    account.logout()
# 要是有1W个地址你写1W行????

# 我们需要改进,用比较好的方式来实现功能

# **************反射:*************所有的主流web框架在干的事
data = raw_input('请输入地址')
array = data.split('/')
userspance = __import__(array[0])  # 导入模块account,array得到的是xxx/xxx中的前一个xxx
func = getattr(userspance, array[1])    # 注意,这个func的返回值就相当于整个函数
func()   # 执行函数
# 详细解析,getattr的第一个参数是我们导入的模块,第二个参数是模块的函数,都是str类型的
# 但是上述代码执行不了  >>>  ImportError: No module named account

分析
data = raw_input('请输入地址')
array = data.split('/')

下面一句执行之后的是 array[0] = account
userspance = __import__(array[0])  

注意  我们自己导入模块的时候:
from backend inport account
所以说上面的userspance是通过account.array[0],并没有加backend

还有一种自己导入模块的方式:
import backend.account
account.login()

所以我们这里的userspance = __import__(array[0])就相当于这一句:
import backend.account(这里的backend是需要加一个字符串的拼接):__import__('backend.'+array[0])

所以说我们想要调用里面的函数的话还得再导入一次,因为上面是account.login(),还需要account这个模块嘛

func = getattr(userspance, array[1])  
func()   
所以,总结一下:
  1. 导入模块的时候加backend这个字符串链接 __import__('backend.'+array[0])
  2. 如果有反射的话,需要再执行一次getattr()

data = raw_input('请输入地址:')
array = data.split('/')
userspance = __import__('backend.'+array[0])
model = getattr(userspance, array[0])
func = getattr(model,array[1])
func()

>>> 请输入地址:admin/index
    欢迎登陆后台管理界面


'''

# -*- coding:utf-8 -*-
"""
@author:Levy
@file:sqlhelper.py
@time:2018/5/1321:51
"""
# 以下显示静态字段的作用


class MsSqlHelper:

    def add(self,sql):
        pass

    def delete(self,sql):
        pass

    def update(self,sql):
        pass

    def select(self,sql):
        pass
# 下面的方法针对每一个业务方,需要创建n多个对象,在内存中开辟n多个空间
ms = MsSqlHelper()
ms.update(sql)
# 下面静态字段发挥作用了


class MsSqlHelper:

    @staticmethod
    def add(sql):    # 注意,不需要self了
        pass

    @staticmethod
    def delete(sql):
        pass

    @staticmethod
    def update(sql):
        pass

    @staticmethod
    def select(sql):
        pass
# 下面我们要使用相关的方法,就可以根据每一个业务就可以直接使用类.去调用方法,就不用创建那么多对象
'''
来一个吊的问题:
python中类的静态方法的作用
    通过不实例化类就可以调用类中的方法
问题来了:
我们不实例化类就直接调用类中的方法   和   我直接调用模块.函数名  有什么区别呢?

1. 在内存里是没有区别的
在类中直接使用@staticmethod字段使得一个方法变成静态方法  在逻辑上是属于这个类的
但是其他的跟外面都是一样的,也就是说,类的静态方法和外面的方法是一样的,只是给了这个方法一个从属关系,它是属于这个类的
 
 鸡肋?
 
 官方解释来了
 
 高手在设计语言的时候,不会做无用功,或者是很少做无用功
 为什么模块有了这个方法之后  又要设计出来静态的这个方法,他们的价值是一样的
 但是,
 python在最初设计的时候,是模块化编程的思想,其实并不支持面向对象
 只要我定义好模块,我想用哪一种方法,在我使用的时候调用这个模块就行了
 所以说python最初是没有静态这个概念的 
 
 静态这个概念是怎么产生的呢? 我在进行面向对象编程的时候,面向对象编程是从java中提出的
 在用java的时候你会发现,在用面向对象的时候必须要new出来东西,也就是要把对象构造出来,才能用里面的方法
 但是一构造,就会在内存的堆里面开辟空间,内存里面有堆有栈什么的,堆里面就会有一块区域专门用来装这些东西
 如果没有静态方法,100个对象在要用数据库的时候,我们就要构造100个方法,这是在面向对象编程中没法避免的问题
 所以java设计出来叫做静态的东西,静态的东西在内存中只保存一份,当我们在调用静态方法的时候,就只会在那个专门的区域中找
 不会给它单独开辟一块区域,所以,静态是专门应对面向对象编程产生的东西
 
 python为什么有了模块化编程之后又有了这个静态呢?
 是因为python想支持面向对象编程,于是乎python又把面向对象的所有的东西拿过来又做了一次
 具体你选择用什么东西,这要看你的个人选择,为什么这个问题会产生?
 因为这是一个历史遗留问题,这是两种编程思想的碰撞。。。
 
 
 模块化编程和面向对象编程两种思想的区别?
 面向对象是灵活性的考虑,能够避免重复的代码
 多态  面向对象存在并且比模块化编程的最大优势所在
 因为类这个东西嘛,和模块形式上差不多的,在编程的时候,你很难在开始的时候就知道要写什么什么类,都是在编程的过程中,
 你觉得这几个方法应该放到一个类中,才会想着把他们变成一个类
python的模块式编程是非常强大的,也可以实现多态
java是强制性语言,在定义的时候你必须告诉我类型是什么

反射 + 模块化编程  ==  面向对象编程   ?
但是用java的时候,就要选面向对象编程
面向对象更多考虑到可扩展性,在做一件事之前,就要考虑好整体的框架
面向函数式编程更像是一个莽夫,走一步写一步,高手来说,可能写的时候整体框架就有了,但是新手还是面向对象吧

'''

# -*- coding:utf-8 -*-
"""
@author:Levy
@file:index.py
@time:2018/5/1321:50
"""

'''
-----------------------------------类和对象-----------------------------------------
注意与之前学习的区别,在类中要有__init__()

class Province(object):
    def __init__(self, name, captial, leader):
        self.Name = name
        self.Captial = captial
        self.Leader = leader

hebei = Province('河北', '石家庄', 'XXX')
shanddong = Province('山东', '济南', '肖震')

三个问题:self是啥,name是啥,是否可以加默认参数    注意类的封装

先看哈,我们传hebei = Province()的三个参数给__init__(),但是self没传,其实pyhton帮你传了,传的是对象名heibei 
我们想要看heibe的省会怎么看?
print hebei.Captial
那这里的hebei就相当于__init__()中的self
class Province(object):
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader):
        #动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader

hebei = Province('河北', '石家庄', 'XXX')
shandong = Province('山东', '济南', '肖震')
print shandong.Captial    属于对象的就用对象.调用                属于对象的就叫做动态字段   类不能访问动态字段
print Province.memo       memo属于类,就用类.调用                属于类的就叫做静态字段     对象能访问静态字段(避免)
>>>济南                                                                                   hebei.memo可以访问
中国的23个省之一

在类里面定义方法,供给对象用的

class Province(object):
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader):
        # 动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader
    # 动态方法,类不能访问,假如访问的话,返回谁?河北?山东? self都不知道是什么,Name也不知道啊------需要实例化
    def sport_meet(self):
        print self.Name + '正在开运动会'

hebei = Province('河北', '石家庄', 'XXX')
shandong = Province('山东', '济南', '肖震')
shandong.sport_meet()   # >>> 山东正在开运动会

有了静态字段,动态字段,动态方法,还缺一个静态方法,如下两步
1. 在动态方法上面加上装饰器 @staticmethod,把原来的动态方法就变成了静态方法
2. 去掉self,因为静态方法属于类,所以不需要self,self是对象,类访问不了对象的东西

class Province(object):
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader):
        # 动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader

    # 动态方法
    def sport_meet(self):
        print self.Name + '正在开运动会'
    # 静态方法
    @staticmethod
    def anti_corruption():       # 去掉了self
        print '每个省都要带头反腐'

hebei = Province('河北', '石家庄', 'XXX')
shandong = Province('山东', '济南', '肖震')
Province.anti_corruption()   >>> 每个省都要带头反腐

特性  
@property   方法的访问形式 变成 字段的访问形式
在绑定属性的时候,如果我们直接把属性暴露出去,虽然写起来简单,但是,没有办法检查参数,导致可以随便把属性的值进行修改
比如:
        s = Student()
        s.score = 9999
这显然不合理啊,为了限制score的范围,可以通过一个set_score()方法来设置成绩(主要进行范围限制),再通过get_score()方法获取成绩
        class Student(object):
            def get_score(self):
                 return self._score
        
            def set_score(self, value):
                if not isinstance(value, int):
                    raise ValueError('score must be an integer!')
                if value < 0 or value > 100:
                    raise ValueError('score must between 0 ~ 100!')
                self._score = value
这样,对于任意的Student实例进行操作,就不能随心所欲地设置score了:
        >>> s = Student()
        >>> s.set_score(60) # ok!
        >>> s.get_score()
        60
        >>> s.set_score(9999)
        Traceback (most recent call last):
          ...
        ValueError: score must between 0 ~ 100!   
但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。
有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?
还记得装饰器(decorator)可以给函数动态加上功能吗?对于类的方法,装饰器一样起作用。
Python内置的@property装饰器就是负责把一个方法变成属性调用的:

class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer')
        if value < 0 or value > 100:
            raise ValueError('score must be 0~100')
        self._score = value

 @property比较复杂,先考虑如何使用,把一个getter方法变成属性只要加上@property
此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值
于是,就有了一个可以控制的属性控件

----------------方法变成了属性调用了----------
>>> s = Student()
>>> s.score = 60    #  实际转化为s.set_score(60)
>>> s.score         #  实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!
---------------------------------------------

注意到这个神奇的@property,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。
还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:
class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2015 - self._birth
上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。
@property广泛应用在类的定义中,可以让调用者写出简短的代码-----少了get和set方法
同时保证对参数进行必要的检查----@birth.setter,这样,程序运行时就减少了出错的可能性


class Province(object):
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader):
        # 动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader

    # 动态方法
    def sport_meet(self):
        print self.Name + '正在开运动会'
    # 静态方法
    @staticmethod
    def anti_corruption(): 
        print '每个省都要带头反腐'

    @property             # bar就是一个只读属性
    def bar(self):
        print self.Name

hebei = Province('河北', '石家庄', 'XXX')
shandong = Province('山东', '济南', '肖震')
hebei.bar   >>>  河北           注意,这里不加括号,因为是特性@property


小结:类里面三种结构了:
字段(静态,动态字段),方法(静态,动态方法),特性(@property)
----------------------公有和私有-----------------------------
私有字段就是__变量名(两个下划线)   可以让你看,但是你不能改,毕竟python的安全机制要差一点
class Province(object):
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader, flag):
        # 动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader
        # 私有字段
        self.__Thailand = flag

    # 动态方法
    def show(self):
        print self.__Thailand

    # 动态方法
    def sport_meet(self):
        print self.Name + '正在开运动会'

    #私有方法
    def __xiao(self):
        print 'I am xiaozhen'

    def zhen(self):
        self.__xiao()
    # 静态方法
    @staticmethod
    def anti_corruption():
        print '每个省都要带头反腐'

japan = Province('日本', '东京', '小泽', True)
print japan.__Thailand    # >>> 报错      直接用对象去访问__.Thailand(私有字段)访问不到      直接不行
japan.show()              # >>> True      但是通过类自己的动态方法去访问私有字段就可以访问得到  间接行
japan.__xiao()            # >>> 报错       对象不能直接访问类的私有方法                       直接不行
japan.zhen()              # >>> I am xiaozhen   通过类自己内部的方法可以访问私有方法           间接行

# 另外一种方式就是利用@property,然后外部通过property来访问类中的私有字段

class Province(object):
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader, flag):
        # 动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader
        # 私有字段
        self.__Thailand = flag

    # 动态方法
    def show(self):
        print self.__Thailand

    # 动态方法
    def sport_meet(self):
        print self.Name + '正在开运动会'

    # 私有方法
    def __xiao(self):
        print 'I am xiaozhen'

    def zhen(self):
        self.__xiao()

    # 静态方法
    @staticmethod
    def anti_corruption():
        print '每个省都要带头反腐'

    @property
    def Thailand(self):
        return self.__Thailand
japan = Province('日本', '东京', '小泽', True)
print japan.Thailand   # >>> True

私有字段可以给你看,不过不让你改   推荐使用下面的方式进行修改和查看私有字段

class Province(object):    # 要先继承Object类,才能实现下面的可写@Thailand.setter
    # 静态字段
    memo = '中国的23个省之一'

    def __init__(self, name, captial, leader, flag):
        # 动态字段
        self.Name = name
        self.Captial = captial
        self.Leader = leader
        # 私有字段
        self.__Thailand = flag

    # 动态方法
    def show(self):
        print self.__Thailand

    # 动态方法
    def sport_meet(self):
        print self.Name + '正在开运动会'

    # 私有方法
    def __xiao(self):
        print 'I am xiaozhen'

    def zhen(self):
        self.__xiao()

    # 静态方法
    @staticmethod
    def anti_corruption():
        print '每个省都要带头反腐'

    @property          # 这里是可读  注意写法:@property
    def Thailand(self):
        return self.__Thailand

    @Thailand.setter   # 这里是可改  注意写法:@Thailand.setter   删了这一段就是可读的
    def Thailand(self, value):
        self.__Thailand = value

japan = Province('日本', '东京', '小泽', True)
print japan.Thailand
japan.Thailand = False
print japan.Thailand
# >>> True   False

继承了object写的话得用@函数名.setter
不继承便可以可读可写

-----------------------------析构函数-----------------------------------
对象创建了得销毁掉吧
注意,析构函数不是自己销毁内存的,销毁内存是python自带的解释器干的,解释器会有一套算法,检查对象是否还有人用,没有人用的话就销毁了
析构函数是这样的,解释器不是有销毁动作嘛,如果你想让解释器销毁的时候做点什么,就写到析构函数里面
怎么写???

class Foo:
    def __init__(self):
        pass
    def __del__(self):  # 析构函数
        print '解释器要销毁我了,我要做最后的挣扎!'
    # 解释器通知一声(就是执行析构函数(__del__)),然后就真的把对象销毁了
    
----------------------------call—--------------------------------
__call__就是一个函数,就是调用方式不一样而已,自己想什么时候用就什么时候用
import time
class Foo:
    def __init__(self):
        pass
    def __del__(self):
        print '析构函数'
    def Go(self):
        print 'Go'
    def __call__(self):
        print 'Call'
f1 = Foo()  # 创建类Foo的对象
f1.Go()   # 对象.方法名调用方法
time.sleep(100)   程序在这里睡一会,但是下面还有对象的调用,所以就不能执行析构函数,析构函数一定是最后执行的,
因为一旦执行了析构函数,就把对象干掉了。
f1()   # 就是对象加上括号就会执行__call__方法

--------------------------------类的继承------------------------------

class Father:
    def __init__(self):
        self.Fname = 'fffff'
    def Func(self):
        print 'father.Func'
    def Bad(self):
        print 'father.抽烟喝酒烫头'
class Son(Father):
    def __int__(self):
        self.Sname = 'sssss'
    def Bar(self):
        print 'son.bar'
    def Bad(self):
        Father.Bad(self)
        print 'son.赌'
s1 = Son()
s1.Bar()
s1.Func()
s1.Bad()
>>>
son.bar
father.Func
father.抽烟喝酒烫头
son.赌

调用父类的构造函数
使用super必须继承object
继承了object  新式类(现在都使用,向面向对象发展)
没有继承Object  经典类


# 下面程序有点疑问,输出结果与视频中的解释不同,day04   24
class Father(object):

    def __init__(self):
        self.Fname = 'fffff'
        # print 'Father.__init__'

    def Func(self):
        print 'father.Func'

    def Bad(self):
        print 'father.抽烟喝酒烫头'


class Son(Father):
    def __int__(self):
        self.Sname = 'sssss'
        print 'Son.__init__'
        Father.__int__(self)
        super(Son, self).__init__()     # 调用父类的构造方法,父类继承object,注意写法 super(Son, self).__init__()

    def Bar(self):
        print 'son.bar'

    def Bad(self):
        Father.Bad(self)
        print 'son.赌'

s1 = Son()
s1.Bar()
s1.Func()
s1.Bad()

# 新式类和经典类的区别
python2.2产生了新式类,2.2之前都是经典类,新式类在经典类的基础上加了一些东西
比如加入了__slot__,只能限制你调用类里面的某一个方法,还有一些其他的,比如__name__,__doc__,__get__,__set__,__delete__
还有一点就是python修复了一个bug,就是经典类在面临多继承的时候可能会出现问题

------------------------------------抽象类--------------------------
自己去看
接口,不能具体实现,只能定义规则
架构师给你一个规范,你写的时候就要按照这个规范去做,不做就会报错

抽象类 + 抽象方法  =  接口(第二种接口,即规范)

from abc import ABCMeta,abstractmethod
class Alert:
    __metaclass__ = ABCMeta

    @abstractmethod
    def Send(selfs):pass

class Wechat(Alert):
    def __int__(self):
        print '__int__'
    def Send(self):      既然继承了接口Alert,就要按照规范去做,去复写里面的抽象方法
        print 'send.Wechat'

f = Wechat()
f.Send()
>>>  send.Wechat
'''





# -*- coding:utf-8 -*-
"""
@author:Levy
@file:Multiple_Inheritance_Problem.py
@time:2018/5/1420:00
"""
'''
# 经典类的多重继承问题
经典类是深度优先,而新式类是广度优先
如何理解呢?
先上图,再上代码:
             class A: (def save(self):...)
            ·       · 
           ·          ·
        classB       classC:(def save(self):...)
            ·        ·
              ·     ·
               classD

# 经典类的写法,不继承object
class A:
    def __int__(self):
        print 'This is A'
    def save(self):
        print 'save method from A'
class B(A):
    def __int__(self):
        print 'This is B'
class C(A):
    def __int__(self):
        print 'This is C'
    def save(self):
        print 'save method from C'
class D(B, C):   # 看好  D继承了B和C,
    def __int__(self):
        print 'This is D'
c = D()   # c是D的对象
c.save()
>>>  save method from A    这就是bug
# c调用save方法,很遗憾D没有,只有去B中去找,很遗憾,B也没有,那么!!!!
# 问题出在这里,c并没有去找另一个继承的类C,而是去找A了,也就是深度优先,这不是我们想要的

来来来  看看新式类  只要A继承了object就可以,其他不用改,结果就是广度优先
也就是说,B没有了之后,c会去C类中去找save()方法,所以结果输出如下所示

class A(object):
    def __int__(self):
        print 'This is A'
    def save(self):
        print 'save method from A'
class B(A):
    def __int__(self):
        print 'This is B'
class C(A):
    def __int__(self):
        print 'This is C'
    def save(self):
        print 'save method from C'
class D(B, C):   # 看好  D继承了B和C,    B和C的摆放也是有讲究的,谁在前面优先执行谁
    def __int__(self):
        print 'This is D'
c = D()   # c是D的对象
c.save()
>>>  save method from C
'''

# -*- coding:utf-8 -*-
"""
@author:Levy
@file:exception.py
@time:2018/5/1420:46
"""
'''
data = raw_input('请输入网址:')
array = data.split('/')

try:
    userspance = __import__('backend.'+array[0])
    model = getattr(userspance, array[0])
    func = getattr(model, array[1])
    func()

except ImportError, e:
    print 1, e
    print '跳转到自定义的404'
except AttributeError, e:
    print 2, e
    print '跳转到自定义的404'
except Exception, e:
    print 3, e
    print '跳转到自定义的404'
else:
    print 'No Error'
finally:
    print '无论出错与否,都会执行这个语句,finally和else都可以没有'

请输入网址:a/b
1 No module named a
跳转到自定义的404
无论出错与否,都会执行这个语句,finally和else都可以没有

请输入网址:account/l
2 'module' object has no attribute 'l'
跳转到自定义的404
无论出错与否,都会执行这个语句,finally和else都可以没有

请输入网址:account/login
login
No Error
无论出错与否,都会执行这个语句,finally和else都可以没有

--------------------------自定义的错误-----------------------------
上面都是python自带的错误,我们想要自己的错误

class MyException(Exception):

    def __int__(self, msg):
        self.error = msg

    def __str__(self, *args, **kwargs):
        return self.error
# obj = MyException('自定义信息错误')
# obj
raise MyException('自定义错误')       这句话是主动触发错误

为什么要主动触发异常呢???主动触发异常有什么作用吗?
来来来  给你瞅一眼作用
下面是一个检验用户登录的函数

def Validate(name, pwd):
     if name == 'xiaozhen' and pwd == '52105210':
         return True
     else:
         return False
try:
    res = Validate('xiaozhen', '123')
    if res:
        print '登录成功'
    else:
        # print '记录日志到数据库'           # 假如else有很多,下面的语句要写很多,我们便可以主动触发异常
        # print '登录失败'
        raise Exception('登录失败')   # 主动触发可以巧妙减少很多代码
except Exception, e:
    print '记录日志到数据库'
    print e

>>>  记录日志到数据库
     登录失败
'''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python笔记.md 是一个用于记录Python编程相关内容的markdown文档。 在Python学习过程中,学习者通常会遇到各种问题和疑惑,需要有一个地方来记录学习笔记和重要概念,以方便日后复习和查阅。Python笔记.md 就是一个很好的选择。 Python笔记.md 可以按照自己的需要来组织内容,比如可以分为不同的章节或主题,并使用markdown语法来格式化文档,使其更加清晰易读。 在Python笔记.md中,可以记录Python的基础语法、常用数据结构、函数、类、模块等内容。此外,还可以记录一些常见的错误和解决方法,以便日后遇到类似问题时能够快速找到解决方案。 Python笔记.md 还可以用来记录自己的思考和理解。在学习过程中,我们常常会思考某个概念或代码背后的原理,这时候可以将自己的思考记录在笔记中,以便后续复习和回顾。 使用Python笔记.md 还可以方便与他人分享学习心得。可以在文档中加入注释或标题,使得文档更加易读和友好。同时,也可以将Python笔记.md 推送到版本控制系统中,与他人共享和共同编辑。 总之,Python笔记.md 是一个非常有用的工具,可以帮助学习者系统地记录、整理和复习Python编程相关的知识和经验。无论是初学者还是有经验的开发者,都可以从中受益,并提高自己的编程技能。 ### 回答2: Python笔记.md是一个使用Markdown语法编写的Python笔记文档。Markdown语法是一种轻量级的标记语言,可以快速地编辑和排版文档。 在Python笔记.md中,可以记录Python程序设计的相关知识、概念和技巧。通过使用Markdown语法,可以方便地插入代码块、链接、图片以及其他强调和排版格式,使得笔记更加直观和易读。 Python笔记.md可以按照不同的章节和主题组织内容,方便快速查找和阅读。在每个章节中,可以记录不同的Python编程概念,如数据类型、控制结构、函数、类等。可以通过示例代码和解释说明来详细解释这些概念的用法和特点。 在笔记中,还可以记录一些Python的常见问题和解决方案,例如常见错误、调试技巧等。这些内容可以帮助初学者更好地理解和掌握Python语言。 此外,Python笔记.md还可以连接到其他的Python资源,如官方文档、教程、在线代码编辑器等。这样可以提供更多的学习和参考资料。 总之,Python笔记.md是一个有条理、易读和方便编辑的Python学习笔记文档,可以帮助人们更好地学习和理解Python编程语言。 ### 回答3: Python笔记md是一种用来记录Python编程语言相关内容的文本文件格式。它使用Markdown语法来快速、简洁地编写和格式化笔记Python笔记md的优点是: 1. 简单易懂:Markdown语法简洁明了,使用起来非常简单,即便没有编程背景的人也能快速上手。 2. 跨平台兼容:无论是在Windows、Mac还是Linux系统中,Python笔记md都可以轻松使用。 3. 可读性强:Python笔记md的文本格式使得代码和说明可以同时显示,方便读者理解和学习。 4. 方便分享和发布:Python笔记md可以导出为HTML或PDF格式,方便分享给其他人或者发布到网络上。 5. 与开发工具兼容:大多数集成开发环境(IDE)和文本编辑器都支持Markdown语法,可以实时预览和编辑笔记。 使用Python笔记md可以帮助程序员记录代码和相关的解释和说明,方便复习和查看。它还可以用于编写技术博客、文档和教育材料等。而且由于其文本格式的特点,Python笔记md也非常适合使用版本控制系统进行版本管理。 总而言之,Python笔记md是一种简单、灵活且易于分享的笔记格式,可以有效提高编程学习和开发的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值