该笔记主要是我自己学习过程中遇到的一些问题,主要内容是对Python - 100天从新手到大师作的笔记和自己的理解(
侵权删)
a='2'
isinstance(a,int)
一般我使用
import math
math.pow(a,b)#来表示a^b
但是也可以直接使用**
来进行指数的运算
1.指定范围内的整数随机数;
from random import randint
face = randint(1, 6)
2.指定范围的浮点数随机数
import random
random.uniform(1, 10)
3.对指定集合的随机选择
import random
random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )
product | 有放回抽样排列 |
---|---|
permutations | 不放回抽样排列 |
combinations | 不放回抽样组合 |
combinations_with_replacement | 有放回抽样组合 |
import itertools
for i in itertools.product('ABCD', repeat = 2):
print(i)
运行结果:
('A', 'A') ('A', 'B') ('A', 'C') ('A', 'D') ('B', 'A') ('B', 'B') ('B', 'C') ('B', 'D') ('C', 'A') ('C', 'B') ('C', 'C') ('C', 'D') ('D', 'A') ('D', 'B') ('D', 'C') ('D', 'D')
import itertools
for i in itertools.product([1,2,3], repeat = 2):
print(i)
运行结果:
(1, 1)
(1, 2)
(1, 3)
(2, 1)
(2, 2)
(2, 3)
(3, 1)
(3, 2)
(3, 3)
from scipy.special import comb, perm
perm(3,2) #计算排列数 6
comb(3,2) #计算组合数 3
在def中定义的变量都是区部变量
def foo():
a = 200
print(a)
def fooo():
a=a+300
print(a)
fooo()
foo()
运行得到:
UnboundLocalError: local variable 'a' referenced before assignment
也就是说在函数fooo中并没有设置变量a,从而无法进行运算
1.第一次修改
def foo():
global a
a=200
print(a)
def fooo():
a=a+300
print(a)
fooo()
foo()
运行得到:
200
----------
UnboundLocalError: local variable 'a' referenced before assignment
在这次的修改中我们在函数foo中对变量a进行global的声明,但是在函数fooo中仍无法对a的值进行修改,这是因为对a进行声明后,函数fooo只对a有使用权,而没有修改权,也可以看下面的例子
a=200
def foo():
a=a+1;
print(a)
foo()
UnboundLocalError: local variable 'a' referenced before assignment
放在外面的a是全局变量,此时foo对a有使用但是没有修改权,但是在同一层级上则可以做修改
a=200
def foo():
print(a)
def fooo():
global a
a=a+300
print(a)
fooo()
foo()
运行得到:
200
500
在fooo中对a做声明后,提高了fooo对变量a操作的权限
createVar = locals()
listTemp = range(1,10)
for i,s in enumerate(listTemp):
createVar['a'+str(i)] = s
print (a1,a2,a3)
str1 = 'hello, world!'
# 通过len函数计算字符串的长度
print(len(str1)) # 13
# 获得字符串首字母大写的拷贝
print(str1.capitalize()) # Hello, world!
# 获得字符串变大写后的拷贝
print(str1.upper()) # HELLO, WORLD!
# 从字符串中查找子串所在位置
print(str1.find('or')) # 8
print(str1.find('shit')) # -1
# 与find类似但找不到子串时会引发异常
# print(str1.index('or'))
# print(str1.index('shit'))
# 检查字符串是否以指定的字符串开头
print(str1.startswith('He')) # False
print(str1.startswith('hel')) # True
# 检查字符串是否以指定的字符串结尾
print(str1.endswith('!')) # True
# 将字符串以指定的宽度居中并在两侧填充指定的字符
print(str1.center(50, '*'))
# 将字符串以指定的宽度靠右放置左侧填充指定的字符
print(str1.rjust(50, ' '))
str2 = 'abc123456'
# 从字符串中取出指定位置的字符(下标运算)
print(str2[2]) # c
# 字符串切片(从指定的开始索引到指定的结束索引)
print(str2[2:5]) # c12
print(str2[2:]) # c123456
print(str2[2::2]) # c246
print(str2[::2]) # ac246
print(str2[::-1]) # 654321cba
print(str2[-3:-1]) # 45
# 检查字符串是否由数字构成
print(str2.isdigit()) # False
# 检查字符串是否以字母构成
print(str2.isalpha()) # False
# 检查字符串是否以数字和字母构成
print(str2.isalnum()) # True
str3 = ' [email protected] '
print(str3)
# 获得字符串修剪左右两侧空格的拷贝
print(str3.strip())
Python中列表常用操作
list1 = [1, 3, 5, 7, 100]
print(list1)
list2 = ['hello'] * 5
print(list2)
# 计算列表长度(元素个数)
print(len(list1))
# 下标(索引)运算
print(list1[0])
print(list1[4])
# print(list1[5]) # IndexError: list index out of range
print(list1[-1])
print(list1[-3])
list1[2] = 300
print(list1)
# 添加元素
list1.append(200)
list1.insert(1, 400)
list1 += [1000, 2000]
print(list1)
print(len(list1))
# 删除元素
list1.remove(3)
if 1234 in list1:
list1.remove(1234)
del list1[0]
print(list1)
# 清空列表元素
list1.clear()
print(list1)
和字符串一样,列表也可以做切片操作,通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表,代码如下所示。
fruits = ['grape', 'apple', 'strawberry', 'waxberry']
fruits += ['pitaya', 'pear', 'mango']
# 循环遍历列表元素
for fruit in fruits:
print(fruit.title(), end=' ')
print()
# 列表切片
fruits2 = fruits[1:4]
print(fruits2)
# fruit3 = fruits # 没有复制列表只创建了新的引用
# 可以通过完整切片操作来复制列表
fruits3 = fruits[:]
print(fruits3)
fruits4 = fruits[-3:-1]
print(fruits4)
# 可以通过反向切片操作来获得倒转后的列表的拷贝
fruits5 = fruits[::-1]
print(fruits5)
list1 = ['orange', 'apple', 'zoo', 'internationalization', 'blueberry']
list2 = sorted(list1)
# sorted函数返回列表排序后的拷贝不会修改传入的列表
# 函数的设计就应该像sorted函数一样尽可能不产生副作用
list3 = sorted(list1, reverse=True)
# 通过key关键字参数指定根据字符串长度进行排序而不是默认的字母表顺序
list4 = sorted(list1, key=len)
print(list1)
print(list2)
print(list3)
print(list4)
# 给列表对象发出排序消息直接在列表对象上进行排序
list1.sort(reverse=True)
print(list1)
t = ('骆昊', 38, True, '四川成都')
print(t)
# 获取元组中的元素
print(t[0])
print(t[3])
# 遍历元组中的值
for member in t:
print(member)
# 重新给元组赋值
# t[0] = '王大锤' # TypeError
# 变量t重新引用了新的元组原来的元组将被垃圾回收
t = ('王大锤', 20, True, '云南昆明')
print(t)
# 将元组转换成列表
person = list(t)
print(person)
# 列表是可以修改它的元素的
person[0] = '李小龙'
person[1] = 25
print(person)
# 将列表转换成元组
fruits_list = ['apple', 'banana', 'orange']
fruits_tuple = tuple(fruits_list)
print(fruits_tuple)
set1 = {1, 2, 3, 3, 3, 2}
print(set1)
print('Length =', len(set1))
set2 = set(range(1, 10))
print(set2)
set1.add(4)
set1.add(5)
set2.update([11, 12])
print(set1)
print(set2)
set2.discard(5)
# remove的元素如果不存在会引发KeyError
if 4 in set2:
set2.remove(4)
print(set2)
# 遍历集合容器
for elem in set2:
print(elem ** 2, end=' ')
print()
# 将元组转换成集合
set3 = set((1, 2, 3, 3, 2, 1))
print(set3.pop())
print(set3)
# 集合的交集、并集、差集、对称差运算
print(set1 & set2)
# print(set1.intersection(set2))
print(set1 | set2)
# print(set1.union(set2))
print(set1 - set2)
# print(set1.difference(set2))
print(set1 ^ set2)
# print(set1.symmetric_difference(set2))
# 判断子集和超集
print(set2 <= set1)
# print(set2.issubset(set1))
print(set3 <= set1)
# print(set3.issubset(set1))
print(set1 >= set2)
# print(set1.issuperset(set2))
print(set1 >= set3)
# print(set1.issuperset(set3))
2019/5/5 学习到day7
class Student(object):
# __init__是一个特殊方法用于在创建对象时进行初始化操作
# 通过这个方法我们可以为学生对象绑定name和age两个属性
def __init__(self, name, age):
self.name = name
self.age = age
def study(self, course_name):
print('%s正在学习%s.' % (self.name, course_name))
# PEP 8要求标识符的名字用全小写多个单词用下划线连接
# 但是很多程序员和公司更倾向于使用驼峰命名法(驼峰标识)
def watch_av(self):
if self.age < 18:
print('%s只能观看《熊出没》.' % self.name)
else:
print('%s正在观看岛国爱情动作片.' % self.name
说明:写在类中的函数,我们通常称之为(对象的)方法,这些方法就是对象可以接收的消息。
面向对象的设计,主要是对权限的考虑,上述的Student类中所有的属性都是可读,且可改写,很多时候我们希望有的属性只能是可读的,有的属性即可读,也可以改写,就需要用到**@property装饰器**,但是要注意的一点是一定要在属性前加上‘_’表示该属性受保护,若没有标记的属性则会报错
class Person(object):
def __init__(self, name, age):
self._name = name
self._age = age
# 访问器 - getter方法
@property
def name(self):
return self._name
# 访问器 - getter方法
@property
def age(self):
return self._age
# 修改器 - setter方法
@age.setter
def age(self, age):
self._age = age
def play(self):
if self._age <= 16:
print('%s正在玩飞行棋.' % self._name)
else:
print('%s正在玩斗地主.' % self._name)
person = Person('王大锤', 12)
person.play()
person.age = 22
person.play()
person.name = '白元芳'
王大锤正在玩飞行棋.
王大锤正在玩斗地主.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-25-60011f3a3ea2> in <module>
3 person.age = 22
4 person.play()
----> 5 person.name = '白元芳'
AttributeError: can't set attribute
在上面的代码中我们修改了王大锤的年龄,使得王大锤可以玩不同的游戏,但是我们无法修改该类的姓名,一旦我们进行操作,也显示无法赋值。
@name.setter
def name(self,name):
self._name=name
这时在类的定义中加入就会增加对应属性的操作权限。
class Person(object):
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
def play(self):
if self._age <= 16:
print('%s正在玩飞行棋.' % self._name)
else:
print('%s正在玩斗地主.' % self._name)
def main():
person = Person('王大锤', 22)
person.play()
person._gender = '男'
person._is_gay = True
person._is_gay
main()
运行得到:
王大锤正在玩斗地主.
True
Python是一本动态类语音,意味着我们可以在class外对class增加新的属性,上述代码中我们临时对Person增加了_is_gay的属性,若是我们希望某个类只有我们我们设置好的固定属性,不可在外部增加,我们可以使用_slots_语句
class Person(object):
# 限定Person对象只能绑定_name, _age和_gender属性
__slots__ = ('_name', '_age', '_gender')
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, age):
self._age = age
def play(self):
if self._age <= 16:
print('%s正在玩飞行棋.' % self._name)
else:
print('%s正在玩斗地主.' % self._name)
def main():
person = Person('王大锤', 22)
person.play()
person._gender = '男'
person._is_gay = True
main()
运行得到:
王大锤正在玩斗地主.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-42-263240bbee7e> in <module>
----> 1 main()
<ipython-input-41-3d900ad7f818> in main()
31 person.play()
32 person._gender = '男'
---> 33 person._is_gay = True
AttributeError: 'Person' object has no attribute '_is_gay'
此时我们就无法就Person类增加新的属性了。
很多情况,我们需要对输入的数据做判断(是否是中文,是否是地球人etc),或者处理后在构建一个类对象;以前我们的做法是,单独写一个函数,其实我们也可以把函数写到class中
class Plus(object):
def __init__(self,number):
self.number = number
@staticmethod
def is_number(number):
return isinstance(number,int)
def plus(self):
print( self.number+1)
a=67
if Plus.is_number(a):
k=Plus(a)
在上面的代码中我们先判断了变量a是否是整数,如果是整数则构建Plus类
看这样一个小问题:现在我要记录一个学生的姓名、年龄、性别,但是我希望先看看该学生的年龄和性别是否符合我大中华第一女校的要求,再决定是否要创建个对象,我们可以分来创建几个判断函数,也可以利用类方法,把事情搞的简单些
class Student(object):
def __init__(self,name,age,gender):
self.name = name
self._age = age
self._gender = gender
@property
def age(self):
return self._age
def gender(self):
return self._gender
@classmethod
def judge(cls,name,age,gender):
t=cls(name,age,gender)
return t.age<20 and t.gender=="女"
Student.judge('老王',34,'老爷们')
运行得到:
False
可以看到,我们将对王大锤的判断写到了class中,使得王大锤暂时也有了Student的类结构,进而更好方便的调用该类中的各个功能。
我们常用@方法
装饰器名称 | @property | @age.setter | @staticmethod | @classmethod |
---|---|---|---|---|
作用 | 表明该属只读 | 表明该属性可改写 | 表明是静态方法 | 表明是类方法 |
注意 | 只对加_的属性 | 只对加_的属性 | 无 | 可以使用参数cls |
类和类之间的关系有三种:is-a、has-a和use-a关系.
类关系 | is-a | has-a | use-a |
---|---|---|---|
含义 | 继承 | 关联 | 依赖 |
例子 | 动物和人 | 汽车和引擎 | 司机和汽车 |
提供继承信息的我们称之为父类
得到继承信息的我们称之为子类
子类比父类拥有的更多的能力,在实际开发中,我们经常会用子类对象去替换掉一个父类对象
class Person(object):
"""人"""
def __init__(self, name, age):
self._name = name
self._age = age
def play(self):
print('%s正在愉快的玩耍.' % self._name)
def watch_av(self):
if self._age >= 18:
print('%s正在观看爱情动作片.' % self._name)
else:
print('%s只能观看《熊出没》.' % self._name)
class Student(Person):
"""学生"""
def __init__(self, name, age, grade):
super().__init__(name, age)
self._grade = grade
@property
def grade(self):
return self._grade
@grade.setter
def grade(self, grade):
self._grade = grade
def study(self, course):
print('%s的%s正在学习%s.' % (self._grade, self._name, course))
stu = Student('王大锤', 15, '初三')
stu.study('数学')
stu.watch_av()
将class 中的object换成了类名Person ,然后利用自己super()._init_()将上一类中name,age做引用,注意在继承关系中,属性只能全部继承,而不能只继承一部分,如果不写的super().__init__,则默认只使用父类的全部属性 , 之后你就可以看到stu可以使用Person中watch_av().
子类在继承了父类的方法后,可以对父类已有的方法给出更新
class Pet(object):
"""宠物"""
def __init__(self, nickname):
self._nickname = nickname
def make_voice(self):
"""发出声音"""
pass
class Dog(Pet):
"""狗"""
def make_voice(self):
print('%s: 汪汪汪...' % self._nickname)
class Cat(Pet):
"""猫"""
def make_voice(self):
print('%s: 喵...喵...' % self._nickname)
def main():
pets = [Dog('旺财'), Cat('凯蒂'), Dog('大黄')]
for pet in pets:
pet.make_voice()
if __name__ == '__main__':
main()
运行得到:
旺财: 汪汪汪...
凯蒂: 喵...喵...
大黄: 汪汪汪...
在cat和dog在继承了pet的属性后重新改写了make_voice的部分,使得不同类可以实现不同的部分
抽象类就是不能够创建对象的类,这种类的存在就是专门为了让其他类去继承它
通过abc
模块的ABCMeta
元类和abstractmethod
包装器来达到抽象类的效果,如果一个类中存在抽象方法那么这个类就不能够实例化(创建对象)
from abc import ABCMeta, abstractmethod
class Pet(object, metaclass=ABCMeta):
"""宠物"""
def __init__(self, nickname):
self._nickname = nickname
@abstractmethod
def make_voice(self):
"""发出声音"""
pass
dog=Pet('二狗')
此时Pet类只能被继承,无法实例化了
运行得到:
TypeError: Can't instantiate abstract class Pet with abstract methods make_voice
通过Python内置的open
函数,我们可以指定文件名、操作模式、编码信息等来获得操作文件的对象
def main():
f = open('致橡树.txt', 'r', encoding='utf-8')
print(f.read())
f.close()
if __name__ == '__main__':
main()
其中’r’表示只读,
操作模式 | 具体含义 | 注意 |
---|---|---|
'r' |
读取 (默认) | |
'w' |
写入(会先截断之前的内容) | |
'x' |
写入,如果文件已经存在会产生异常 | |
'a' |
追加,将内容写入到已有文件的末尾 | |
'b' |
二进制模式 | 不能单独使用,参数写为’rb‘或者’wb’ |
't' |
文本模式(默认) | |
'+' |
更新(既可以读又可以写) | 不能单独使用,一般用’r+’ |
将文本信息写入文件文件也非常简单,在使用open
函数时指定好文件名并将文件模式设置为'w'
即可
f='abc.txt'#创建txt文件
w=open(f,'w+',encoding='utf-8')#打开txt文件,并使用‘+’模式
w.write('鸡你太美\n') #进行写入
w.read()#查看写入
w.seek(0) #将光标调回首位
w.close#关闭文件
注意之所以要调整光标,是因为read()或者write执行后,会将光标放置在文本末尾,若是再一次使用read(),则反馈为空
c='b.txt'
w=open(c, 'w+',encoding='utf-8' )
for i in range(10):
w.write('%s\n'%i)
w.seek(0)
line=w.readlines()
print(line)
w.close()
注意 : 创建文本,打开的操作只能是’w’或者’w+'不能是其他模式,否则会报错
如果open
函数指定的文件并不存在或者无法打开,那么将引发异常状况导致程序崩溃,我们可以将那些在运行时可能会出现状况的代码放在try
代码块中,在try
代码块的后面可以跟上一个或多个except
来捕获可能出现的异常状况
def main():
try:
with open('致橡树.txt', 'r', encoding='utf-8') as f:
print(f.read())
except FileNotFoundError:
print('无法打开指定的文件!')
except LookupError:
print('指定了未知的编码!')
except UnicodeDecodeError:
print('读取文件时解码错误!')
if __name__ == '__main__':
main()
通过with
关键字指定文件对象的上下文环境并在离开上下文环境时自动释放文件资源,也就是执行完with下的语句后自动关闭
from random import randint
from threading import Thread
from time import time, sleep
def download(filename):
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
start = time()
t1 = Thread(target=download, args=('Python从入门到住院.pdf',))
t1.start()
t2 = Thread(target=download, args=('Peking Hot.avi',))
t2.start()
t1.join()
t2.join()
end = time()
print('总共耗费了%.3f秒' % (end - start))
if __name__ == '__main__':
main()
直接使用threading模块的Thread
类来创建线程
**start()?*启动线程活动。
join(): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
一般语法为
from threading import Thread
Thread(function,args())
function - 线程函数。
args - 传递给线程函数的参数,他必须是个tuple类型。
13-days , 这里只写了一小部分,详细的可见原作者的slide