写作缘起
从2019年3月辞职以来,一直在补以前没有学完的外汇课程,截止到今年3月, 终于学完了。手动交易的时候,还有一些人人都有的困难(比如那句老话let your profit run)难以克服。 19年夏天,无意间下载了一段李笑来在微信群里讲Python的音频,听了之后很受触发,开始接触Python。今年6月开始,学习MQL4和MQL5,发现尤其是MQL5, 和Python的交互很好,并且python用于做策略分析也强大。于是在逻辑教育报了2门课,一个是数据分析,一个是爬虫。目前在学习python基础课,Jerry老师布置了作业,每节课都要写一些。
基础VIP课程一共15节,笔记都在这一篇里面。
后续我还将更新python爬虫笔记,python 数据分析的笔记还有MQL4, MQL5的笔记。
##第一节 计算机要点
有几点关于代码的要求特别有感触
代码要写3遍,第一遍按照老师的视频和要求写;
#####第二遍脱离老师的视频,再去写一遍原码。
#####第三遍按照自己的理解去写。 我从2002年第一次自学VB开始,从来没有这么写过,当然大部分时候都是看书自学,这是第一次跟着视频学习。我觉得经过这3遍,大部分人对代码都会有很深刻的认识了。
第一节课讲得都是比较基础的东西,计算机概念(老师居然没有提到冯诺依曼对计算机的架构的改进),TUI和GUI,DOS代码,纯文本和富文本,常见的字符集,16进制等。
第二节课笔记
环境变量,以前MATLAB编程用的多,从来不知道有这个概念。通过添加按钮来添加环境变量,也可以修改或者删除。
通过pip install可以安装一些模块和库,用CMD安装有时候失败,国内有不少换源安装的服务器,比如豆瓣,阿里,中科大和清华。连接国内的换源安装服务器,既快又方便。
pycharm的安装我以前就会了,这次老师又教了虚拟环境和路径的选择,3月安装的时候,直接设立了全局模式,这次通过虚拟模式,一下多了好几个选择。
第三节课主要讲了表达式,语句,函数的概念,关键字,命名规则,基本数据类型。变量的概念,变量名。
从第三节课开始,终于开始敲代码了,下面是我第一遍敲的,明天再敲2遍
d1={‘python’: ‘Java’}
import copy
d2=copy.deepcopy(d1)
print(d1)
print(‘hello world’)
print(d2)
print(id(d1),id(d2))
print(d1==d2)
print(123,’\n’,456)
第四节课主要讲了格式化字符串,其中占位符,f.format 看着就眼生。
针对字符串的操作,和excel里面的函数用法基本一样,max,min, len,lower,upper等不常用的就是join,去空格。
非布尔值的与或运算,比较运算符,条件运算符,都是很熟的概念了。
这节课我很陌生的代码如下:
import bs4
s='s=%s, s2= %s '%(‘hello’,‘python’)
print(s)
s1=‘钢铁侠’
s2=‘蜘蛛侠’
r=f’hello{s1},{s2}’
print ®
s=‘i like{1},{1}’
a=s.format(‘python’,‘java’)
print(a)
a=‘abc’
r=’-’.join(a)
print®
x=7//3 #取整
y=7%3 #取余
z= 25**0.5 # 开平方
print(x)
print(y)
print(z)
print(ord(‘a’),ord(‘b’))
print(1==True)
f=1 is True # is 比较的是对象的ID,也就是在内存中的位置
print(f)
对于非布尔值,非运算会将其先转换为布尔值,然后再取反
#对于0, None,这些表示空性的值,都会转换成false
h=None
h=not h
print('h= ',h)
m= true and true
m= 1 and 2
print('m= ',m)
r=0 or 3
print ®
第五节课
python对于缩进的要求比mql4等语言要求高的多,我发现我经常在这里犯错误。 这次讲了任何语言的基础,包括if ,else,while, for, break和continue的用法。break 和continue还是比较简单,而循环衍生出的命题可谓无穷无尽了。
b = 2 or 3 and 4
print(b)
if False: print(‘hello’)
if True: print(‘hello2’)
num=50
if num>20: print(‘hello1’)
content=input( )
content=int(content)
if content>20000:
print('ok')
else:
print(‘mnifjaio’)
r=0
i=0
while i<100:
i=i+1
if i%2==0:
r=r+i
print(i)
print®
i=0
while i<5:
print('********')
i = i + 1
i=0
while i<5: #控制高度
j=0
while j<15: #控制宽度
print('*', end='')
# print('*', end='')
# print('*', end='')
# print('*', end='')
# print('*', end='')
j=j+1
print()
i=i+1
i=0
while i<5:
j=0
while j<5-i:
print(’*’, end=’’)
j=j+1
print()
i=i+1
i = 0
while i < 5:
j = 0
while j <i+1:
print('*', end='')
j = j + 1
print()
i = i + 1
i=0
while i<9:
i=i+1
j= 0
while j<i:
j = j + 1
print(f’{j}{i}={ji}’ , end=’’)
print()
i=0
while i<6:
i=i+1
if i==3:
continue
print(i)
else:
print(‘hello’)
i = 0
while i < 6:
i = i + 1
if i == 3:
break
print(i)
else:
print(‘hello’)
第六节 主要讲了怎么对列表进行操作,乘法,加法, in, not in, len max min, s.index s.count s.append,s.insert,s.pop, s.remove, s.clear,s.reverse,s.sort
代码太简单了,这里就不写了,我打了大约80行代码,其中一半都是print
周三老师有事没来上课,周五上的是第七节课,这节课讲的也比较简单,元组的性质:不可变序列,元组不能为空,至少为,.元组的解包。然后讲字典,键值对,各种函数,dict,get,update,del,pop,copy. 遍历字典的方法,d.key, d.value, ditem. 最后讲了集合,集合只能存储不可变对象,集合存储的对象是无序的,集合不能出现重复元素。set函数可以创建集合。
这次课的代码我敲了有104行,和上次差不多,基本一半都是print,看看结果。
第8节课 讲了集合和函数
集合用的比较少,讲的也很快,基本都是前面的函数+高一上学期的数学。函数有len, add,update,pop,remove,clear. 集合的运算,交集,并集,异或集
可变对象的三要素: id,type. value
函数一共分3节课,这次是第一节,函数也是对象,函数的参数有实参和形参,函数的传递方式,不定长参数有2个,一个解决位置,一个解决其他关键字。
下面是本节课的代码:
s={1,2,3,4,‘a’,‘b’}
print(s)
s.add(5)
print(s)
s3={10,20,30,40,‘as’,‘bp’}
# s.update(s3)
# print(s)
# r=s.pop()
# print®
# s.remove(2)
# print(s)
s2={3,4,5,6,7}
r=s&s2
print®
r1=s|s2
print(r1)
r2=s-s2
print(r2)
r3=s2-s
print(r3)
r4=s^s2
print(r4)
a=[1,2,3]
print(a,id(a))
a[0]=10
print(a,id(a))
a=[4,5,6]
print(a,id(a))
b=a
b[0]=100
print(b,id(b))
#函数也是一个对象,
函数用来保存一些可执行的代码没在你需要的时候可以对这些语句进行多次调用。
def s():
print(1+1)
s()
def fn(a,b,c=20):
print(a)
print(b)
print©
fn(1,2,3)
fn(1,2)
#关键字传参,可以不按照定义的顺序去传递,根据参数名去传递参数
#必须将位置参数写在关键字参数的前面
#在函数中对形参进行赋值,不会影响其他的变量
#当我们通过形参去修改对象时,会影响到所指该对象的变量
def fn3(a):
a=20
print(a)
c=10
fn3©
print©
def fn4(a):
a[0]=20
print(a,id(a))
c=[1,2,3]
#fn4(c.copy()) #传递副本
fn4(c[:])
print(c,id©)
def fn(*a):
print(a,type(a))
r=0
for n in a :
r=r+n
print®
fn(1,2,3,3,5,)
#** 形参可以接收其他关键字参数,他会将这些参数统一保存到一个字典
当中,**形参也只能有一个,并且必须卸载所有参数的后面
def fn23(**a):
print(a,type(a))
*argument 解决位置参数
fn23(b=1,d=2,c=3)
def fn(a,b,c):
print(a)
print(b)
print©
t=(4,5,6,7,8,9)
d={‘a’:1,‘b’:2,‘c’:3}
fn(*d)
fn(**d)
第九课,函数课程第二节,挺难的,这节课讲到了递归。除此以外,讲了函数的返回值,return,help函数,global函数,locals函数返回一个字典。递归的2个条件,基线条件和递归条件,课程代码
def fn(*args):
r=0
for n in args:
r=r+n
print®
fn(1,2,3,4)
def fn2():
return
r=fn2()
print®
def fn4():
for i in range(5):
if i==3:
break
print(i)
print(‘it is done’)
fn4()
def fn4():
for i in range(5):
if i==3:
return
print(i)
print(‘it is done’)
# break 退出当前循环
#return 函数结束
#continue 跳出当次循环
#fn 是函数对象,打印fn就是在打印函数对象
#fn()调用函数,打印fn实际上就是在打印fn()的返回值
fn4()
help(print)
def fn():
a=123
print(‘函数内部: a=’,a)
fn()
def fn2():
a=30
def fn3():
print(a)
fn3()
fn2()
def fn2():
a=30
def fn3():
a=40
print(a)
fn3()
fn2()
a=123
def fn2():
global a
a=30
print(a)
fn2()
print(a)
a=123
b=345
scope=locals()
print(a)
print(scope[‘a’])
scope[‘c’]=789
print©
n=10
for i in range(1,10):
print(i)
n=n*i
print(n)
def fn(n):
r=n
for i in range(1,n):
r=r*i
return r
print(fn(30))
#递归是解决问题的一种思想,它和循环很像
#它的整体思想是把一个大的问题分解成为一个小的问题,直到问题无法分解
#递归函数的两个条件
#1 基线条件,问题可以被分解为最小的问题,当满足基线条件时,递归就不执行了
#递归条件,将问题继续分解的条件
def fn2(n):
if n==1: #基线条件
return 1
return n*fn2(n-1) #递归条件
print(fn2(10))
def fn1(n,i):
if i==1:
return n
return n*fn1(n,i-1)
print(fn1(8,8))
def fn2(s):
if len(s)<2:
return True
elif s[0]!=s[-1]:
return False
return fn2(s[1:-1])
print(fn2(‘abcba’))
s=‘abcdcba’
print(s[1:-1])
第10节课,函数已经全部讲完,从下节课开始就要讲面向对象编程了。这节课讲了高级函数,闭包(通过闭包可以创建一些只有当前函数才能访问的变量,可以将一些私有数据藏到闭包当中),形成闭包的条件有函数嵌套,内部函数作为返回值返回,内部函数必须使用外部函数变量。 装饰器引入的原因,修改比较多麻烦,不方便维护,会违反开闭原则。装饰器的使用,通过装饰器,可以在不修改原函数的情况下,来对函数进行一个扩展,@XX即可。
本章节的源码,把上节课的作业也附上了,上节课作业我不会做,因为基线的拆解有问题,我认为最基本的拆解是3个汉诺塔,老师的拆解更为基础。另外讲了一点衍生知识,比如冒泡排序,快速排序
#高阶函数
#特点1: 接收一个或者多个函数作为参数
#2,函数作为返回值返回
lst=[1,2,3,4,5,6,7,8,9,10]
def fn(lst):
new_lst=[]
for n in lst:
if n%2==0:
new_lst.append(n)
return new_lst
print(fn(lst))
lst=[1,2,3,4,5,6,7,8,9,10]
def fn(lst):
def fn2(i):
if i%2==0:
return True
def fn3(i):
if i>5:
return True
return False
new_lst=[]
for n in lst:
if fn3(n):
new_lst.append(n)
return new_lst
print(fn(lst))
lst=[1,2,3,4,5,6,7,8,9,10]
def fn2(i):
if i % 2 == 0:
return True
def fn3(i):
if i > 5:
return True
return False
def fn4(i):
if i%3==0:
return True
return False
def fn(fnc,lst):
new_lst=[]
for n in lst:
if fnc(n):
new_lst.append(n)
return new_lst
print(fn(fn4,lst))
lst=[1,2,3,4,5,6,7,8,9,10]
def fn4(i):
if i%3==0:
return True
return False
print(filter(fn4,lst))
print(list(filter(fn4,lst)))
def fn5(a,b):
return a+b
print(fn5(1,2))
print((lambda a,b:a+b)(50,60))
fn6=(lambda a,b:a+b)
print(fn6(5,6))
lst=[1,2,3,4,5,6,7,8,9,10]
r=filter(lambda i:i%3==0,lst)
print(list®)
def fn():
def fn2():
print(‘i am fn2’)
#将内部函数fn2作为返回值返回
return fn2
print(fn())
r=fn()
r() #打印的是函数对象,可以直接调用
def fn():
a=10
def fn2():
print(‘i am fn2’,a)
#将内部函数fn2作为返回值返回
return fn2
print(fn())
r=fn()
r() #打印的是函数对象,可以直接调用
nums=[1,2,3,4,5,6,7,8,9]
print(sum(nums)/len(nums))
num2=[]
def fn1(n):
num2.append(n)
return sum(num2)/len(num2)
print(fn1(10))
print(fn1(40))
#形成闭包的条件 1 函数嵌套,2将内部函数作为返回值返回3 内部函数必须使用到外部函数的变量
def make_fn():
num2=[]
def fn1(n):
num2.append(n)
return sum(num2)/len(num2)
return fn1
m=make_fn()
print(m(10))
print(m(40)) #这样num2 就安全了
def add(a,b):
return a + b
def mul(a,b):
return a *b
def fn():
#return a+b
print('i am a function ')
def fn2():
print(‘function starts’)
fn()
print(‘function ends’)
def new_add(a,b):
print(‘function starts’)
r=add(a,b)
print(‘function ends’)
return r
r=new_add(1,2)
print®
#装饰器的使用:定义一个函数来对其他函数进行扩展,是其他函数可以在执行前打印开始执行,
#执行后打印执行结束
start-end 这一类函数,我们就称之为装饰器
#通过装饰器,可以在不修饰原来的函数的情况下对函数进行扩展
def fn():
#return a+b
print('i am a function ')
def add(a,b):
return a + b
def start_end(old):
def new_function(a,b):
print(‘function starts’)
r=old(a,b)
print(‘function ends’)
return r
return new_function
f=start_end(add)
r=f(1,2)
#f2=start_end()
print®
def fn():
#return a+b
print('i am a function ')
def add(a,b):
return a + b
def start_end(old):
def new_function(*args,**kwargs):
print(‘function starts’)
r=old(*args,**kwargs)
print(‘function ends’)
return r
return new_function
f=start_end(add)
r=f(123,456)
#f2=start_end()
print®
@start_end
def speak():
print(‘keep the good’)
speak()
def hannuotower(num,a,b,c):
#参数num 代表盘子, abc代表柱子。如果有一个盘子,A-C,如果有2个盘子
#以上,可以把他看成2个group,最下面的和其他。先把最上面的group放入B
#把最下面的盘子到A-C。 把b柱的group弄到C
#基线条件
#如果只有一个盘子A-C
if num==1:
print(‘the 1st pan from’ ,a, ‘->’, c)
else:
hannuotower(num-1,a,c,b)
print(‘the’, num, ‘pans from’,a, ‘->’, c)
hannuotower(num - 1, b, a, c)
hannuotower(10,‘A’,‘B’,‘C’)
#这是分治算法:可以解决大整数的乘法,二分搜索,快速排序,汉诺塔问题
倒数第五节课,时间飞逝啊。python是一门面向对象的编程语言。面向过程 孩子吃瓜这个案例。类的简介:内置对象, class,类就是对象的图纸,如果多个对象是通过一个类创建的,我们就称之为这些对象是一类对象。
类的说明,事物有数据(属性),行为(方法)。讲了属性方法的查找流程。 一般情况下,属性都保存到类对象中。self 参数,在定义方法的时候会默认传递self 参数,self是指类的实例。
我以前实践过的代码主要是C,MQL4(基础也是C)还有matlab。很少接触类,虽然自学过C++但是基本没有实际应用过。 这节课我敲的代码不多,因为多数是概念问题,把老师的注释都敲了。
#对象就是内存中专门用来存储数据的一块区域
#对象的结构有ID(标识),type(类型),value(值)
#面向过程,就是将程序的逻辑分解成一个一个的步骤,
我们通过完成一个一个的步骤来完成一个程序;这种方式写代码只适用于一个功能,
符合人类的思维逻辑,编写起来比较简单。
类,class,简单理解相当于一张图纸,
在程序中我们需要根据类来创建对象。
如果多个对象是通过同一个类创建的,
我们就称这些对象是一类,下面创建一个空对象
class MyClass():
pass
print(MyClass)
mc=MyClass()
mc.name=‘葫芦娃’
print(mc,type(mc))
print(mc.name)
#isinstance() 用来检测一个对象是否是一个类的实例,
返回值是布尔类型,类也是一个对象,
类是一个用来创建对象的对象;
类是type类型的对象 可以向对象中添加变量,对象中的变量称为属性
#语法 对象.属性名 = 属性值。对现实生活中事务的抽象
r=isinstance(mc,MyClass)
print®
class Person:
#在类中有代码块,我们可以定义变量和函数
#在类中我们定义的变量,将会成为所有实例对象的公共属性
#所有的实例都可以访问这些变量,在类中可以定义函数,我们称之为方法
#pass
# 这些方法也可以通过该类的实例来访问.方法调用和函数调用的区别。
# 如果是方法调用,有几个形参,就传递几个实参。
# 如果是方法调用,默认传递一个形参,
# 所以在定义方法的时候至少得有一个形参
# 函数会成为该类实例的公共方法,
# 所有该类的实例都可以通过对象.方法名的方式来调用
# 类对象和实例对象都可以保存属性和方法
# 如果这个属性方法是某个实例独有的,则应该保存到实例对象当中.
a=1
b=2
name=‘葫芦娃’
#方法每次被调用的时候,解析器会主动传递一个实参
#如果是P1调用,则第一个参数(a)就是P1 对象
# 如果是P2调用,则第一个参数(a)就是P2 对象
#一般都会命名这个参数为self
def speak(a):
#print(‘i am doing great’)
print(a.name)
p1=Person()
p2=Person()
print(p1.name)
print(p2.name)
p2.name=‘钢铁侠’
print(p2.name)
p1.speak()
p2.speak()
<main.Person object at 0x00000207415F7A90> a 是对象,不同地址
<main.Person object at 0x0000020741609400>
从周三开始连续出差,周六晚上才回来。功课落下了不少。
类的第二节讲了特殊方法init,和2种封装。封装出现的原因,getter方法和setter方法。双划线和单划线XXX,最后讲了property装饰器,整体思路特别流畅。本节课代码如下:
#我们希望在创建对象的时候,必须设置name属性,如果不设置则对象无法创建
#在类中有一些特殊方法(魔术方法),特殊方法以下划线开头结尾
class Person:
name = ‘葫芦娃’
#print(‘first word in the class’) #类中的代码先执行,并且只执行一次
def init(self,name):
self.name=name
# print(‘init has been executed’)
#特殊方法不需要我们自己调用
#特殊方法会在特殊时候自己调用
# print(self)
def speak(self):
print(‘hello, i am%s’%self.name)
p1=Person(‘gangtiexia’)
#p1.init()
p2=Person(‘zhizhuxia’)
# p3=Person()
p1.speak()
p2.speak()
class Car():
name=‘XXX’
def init(self,name,color):
self.name= name
self.color= color
def run(self):
print(‘this car runs fast’)
def baba(self):
print(’%s didididi’%self.name)
c=Car(‘benz’,‘red’)
print(c.name,c.color)
c.name=‘frari’
c.color=‘black’ #可以通过对象。属性的方式来修改属性值,
# 这种对象导致对象中的属性值可以任意修改,不安全。我们
# 可增加安全性1 属性值不能随意修改,
# 属性不能改为任意值,
# 封装是面向对象的三大特性之一,
# 封装指的是隐藏对象中一些不希望被外部访问到的属性或者方法
# 如何隐藏属性,将对象的属性名修改成一个外部不知道的名字
将对象的属性名修改成一个外部不知道的名字,如何获取对象中的属性
需要我们提供一个get和set方法来访问属性和修改属性
使用封装,的确增加了类定义的复杂程度,但是他确保了属性的安全
隐藏了属性名,使得调用者无法随意修改对象属性
增加了get 和set方法,控制了只读
如果希望属性只读,则可以直接去掉set方法
如果希望属性不能被外部访问,则可以去掉get方法
使用set来设置属性时候,可以增加数据验证,.
c.run()
# c.baba()
class Dog:
def init(self,name,age):
self.hidden_name=name
self.hidden_age = age
def speak(self): #获取对象的name 属性
print(‘hello i am %s’%self.hidden_name)
def get_name(self):
return self.hidden_name
def set_name(self,name): #修改对象的name 属性
self.hidden_name=name
d=Dog(‘daheibei’)
# d.hidden_name =‘erha’
# d.speak()
print(d.get_name())
d.set_name(‘dalangqing’)
print(d.get_name())
d.speak()
#可以对对象属性使用双下划线
#双下划线的属性是对象的隐藏属性,隐藏属性只能在类的内部访问,
无法通过对象访问
一般我们会将一些私有属性以_开头。
class Person:
def init(self,name):
#self.hidden_name=name
#实际上名字改为_Person__name
self.__name = name
self._name = name
def get_name(self):
return self.__name
def set_name(self,name):
self.__name=name
p=Person(‘huluwa’)
#p.set_name(‘sheyao’)
#p.hidden_name=‘laoyeye’
p.__name=‘canglaoshi’
print(p._Person__name)
p._Person__name=‘laoyeye’
print(p.get_name())
class Person:
def init(self,name):
self._name=name
#property 用来将方法转换为相同名称的只读属性
@property
def name(self):
print(‘get method has been executed’)
return self._name
@name.setter
def name(self,name):
self._name = name
p=Person(‘huluwa’)
#print(p.name())
p.name=‘super man’
print(p.name)
import requests
r=requests.get(‘https://www.baidu.com/’)
print(r.text)
类的最后一节课
主要讲了继承和多态,比起那个递归,简单到不行了。下面是笔记和源码的混合
#继承,是面向对象的三大特性之一
我们使用继承是可以获取到另外一个类的属性和方法
在定义类的时候,我们可以在类名的括号中指定当前的父类(超类,基类。
让类与类之间产生了关系。有了这个关系才有多态的特性
提高了代码的复用性。
class Person:
name=’’
age=’’
class Doctor:
def cure(self):
print(‘save life’)
class Soldier:
# name=’’
# age=’’
def study(self):
# print(‘protect country’)
class Animal:
def init(self,name):
self._name=name
def run(self):
print(‘it can run’)
def sleep(self):
print(‘it can sleep’)
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name=name
def speak(self):
print(‘i can keep home’)
# a=Animal()
# a.run()
#在创建类的时候,如果省略了父类,则默认父类为object
#如果子类中有和父类重名的方法.则通过子类去调用该方法时,
# 会调用的是子类里面的方法,这称之为方法的重写或者覆盖
# 当我们调用一个对象的方法时会优先去当前对象寻找是否有该方法,
# 有则直接调用,没有则在当前对象的父类 中寻找,以此类推 。
class Dog(Animal):
#希望可以直接调用父类的init方法来初始化父类中定义的属性
# super()可以用来获取当前类的父类.通过super()
# 调用父类方法时候,不需要传递self
def init(self,name, age):
# Animal.init(self,name)
super().init(name)
self._age=age
#父类中的所有方法都会被子类继承
d=Dog(‘zangao’)
d.name='dalanggou ’
print(d.name)
print(d )
d.run()
d.sleep()
d.speak()
r=isinstance(d,Animal)
print®
print(issubclass(Dog,Animal))
print(issubclass(Dog,object ))
print(issubclass(int,object ))
#__base__可以获取当前类所有的父类
#python中是支持多重继承的,可以在类名后面添加多个类
实现多重继承。这可以是的子类同时拥有多个父类,
并且会获取到所有父类的方法,如果多个父类中有重名的方法
则先去第一个父类中寻找,然后第二个,第三个,
class A(object):
def test(self):
print(‘a’)
class B(object):
def test(self):
print(‘b’)
class C(B,A):
pass
print(C.bases)
c=C()
c.test()
#c.test2()
#多态是面向对象的三大特性之一,一个对象可以以不同的形态去呈现。
class A:
def init(self,name):
self.name=name
def len(self):
return 100
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name=name
class B:
def init(self,name):
self.name=name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name=name
class C:
pass
a=A(‘huluwa’)
b=B(‘cang jing kong’)
c=C()
def speak(obj):
print(‘hello %s’%obj.name)
def speak3(obj):
if isinstance(obj,A): #做了类型检测,只有在A里实例才行
print(‘hello %s’%obj.name)
#speak©
#speak3(b)
print(len(a))
#面向对象的三大特征:
封装:确保对象中的数据安全,
继承:保证了对象的可拓展性,
多态:保证了程序的灵活性
倒数第二节课了,虽然课程比较紧张,终于把主要的语法内容学完了。这节课讲了属性和方法,类属性,实例属性,类方法,实例方法,静态方法。模块化的意义。模块的创建,import name main 模块的使用
语法 模块名,变量名(函数名,对象名)
import xxx
import xxx as yyy 比较常用
另外讲了列表推导式,生成器 yield关键字
print(’ this is my first’)
print(name) # main 表示当前的文件为主文件
在每个模块都有一个__name__
通过它完美可以获得当前引入模块的名字
a=1
b=2
def test1():
print(‘test1’)
class Person:
def __init__(self):
self.name='cang jing kong'
#以下代码纯属测试程序, 只有当前文件是主文件才执行,否则不执行
if name==‘main’
test1()
class A:
count=0
#类属性 直接在类中定义属性
# 类属性只能通过类对象修改,无法通过实例对象来修改
# 实例属性,通过实例对象添加的属性我们称之为实例属性。
def init(self):
self.name=‘葫芦娃’
#这是实例属性,因为他是通过实例对象添加的属性
#实例属性只能通过实例对象来访问和修改,
# 类对象无法访问和修改
#实例方法
def test(self):
print(‘this is a test method’)
#在类中定义类方法:
@classmethod
def test2(cls):
print(‘this is a class method’,cls)
print(cls.count)
@staticmethod # 静态方法基本上都是一个与本类无关的方法
#静态方法都是一些工具方法 。
def test3():
print(‘this is test3, a static method’)
a=A()
# a.count=20
# print(a.count)
# print(A.count)
#print(‘a’,a.name)
#print(‘A’,A.name) 大A无法访问
#a.test()
#A.test(a)
#A.test2()
#a.test2() #类方法可以通过类调用也可以通过实例调用
a.test3()
A.test3()
#在python当中一个py文件就代表一个模块
模块的创建
在一个模块中引入其他模块
1 import 模块名(python的文件名)
import 模块名 as 模块别名
模块的使用
访问模块中的变量,语法,模块名,变量名
我们也可以引入模块中的部分内容,语法from 模块名 import 变量
语法from 模块名 import 变量 as 别名
from test_m import test1 as new_test1。
import test_m
print(test_m)
import test_m as test
# print(test.a,test.b)
test.test1()
p=test.Person()
print(p.name)
from test_m import Person,test1,a
p1=Person()
print(a)
#旧的列表-新的列表
#语法1 [表达式for 变量 in 旧列表]语法2[表达式for 变量
in 旧列表 if 条件] 。
lst=[‘jerry’,‘tony’,‘tom’,‘ann’,‘mike’]
def fn(lst):
new_lst=[]
for name in lst:
if len(name)>3:
new_lst.append(name)
return new_lst
lst=[‘jerry’,‘tony’,‘tom’,‘ann’,‘mike’]
r=[name for name in lst if len(name)>3]
new_lst=[num for num in range(1,101) if num%30 and num%60]
print(new_lst)
在python中有一边循环一遍计算的机制称之为生成器
new_lst=[x*3 for x in range (10)]
g=(x*3 for x in range (10))
print(new_lst)
print(type(g))
print(g.next())
print(g.next())
print(g.next())
print(next(g))
print(next(g))
print(next(g))
#定义生成器方式二,通过函数来完成
#只要在函数中添加yield关键字,就变成了一个生成器函数。
def fn():
n=0
while True:
n=n+1
yield n
#return n
n=fn()
print(n)
print(next(n))
print(next(n))
最后这堂课比较简单,主要讲了异常的简介,异常的传播,异常对象,我呢间打开,关闭文件,读取文件和写入文件
#程序一旦出现异常,会导致程序立即终止,异常后棉的代码都不会执行
try语句 代码块(可能出现错误的语句,
except:代码块(出现错误以后处理的的处理方式
else:代码块(没有出现错误的语句。
print(‘hello’)
try:
print(6/0)
except:
print(‘there is an error’)
else:
print(‘程序正常执行没有错误’)
print(‘java’)
#异常的传播,当函数中出现异常的时候,如果在函数中对异常进行了处理
#则异常不会继续传播 ,
def fn():
print(‘hello fn’)
print(6/0)
try:
fn()
except:
pass
def fn():
print(‘hello fn’)
print(6/0)
def fn2():
print(‘hello fn2’)
fn()
def fn3():
print(‘hello fn3’)
fn2()
fn3()
print(‘异常出现前’)
try:
#print(abc)
print(6/0)
#except NameError:
except Exception as e:
#如果except后面不跟任何内容,则此时他会捕获所有的内容
#如果except后面跟一个异常类型,它只会捕获该类型的异常
print(‘deal with exception logic’,e)
print(‘after exception’)
#文件(file)
#通过python程序来对计算机中各种文件进行增删改查的操作I/O
#file_name=‘demo.txt’
#file_obj=open(file_name)
print(file_obj)
#读取内容
#read()方法来读取文件的内容,把读取的内容以字符串来返回
content=file_obj.read()
print(content)
file_obj.close()
#with as 语句
#一旦with as 语句结束,文件自动关闭
with open(file_name) as file_obj:
print(file_obj.read)
调用open()来打开一个文件的时候,可以将文件分为两种类型
第一种是纯文本 使用utf-8编写的文本文件
第二种是二进制文件 比如音频视频图片
read来读取内容的时候,会直接将全部内容读取出来
如果要读取的内容比较大,会一次性加载到内存当中,导致内存溢出
read可以接收一个size作为参数,该参数用来指定读取字符的数量,
默认值为-1.读取全部内容
可以为size指定一个值,这样会读取指定数量的字符
每一次读取的位置都是从上一次读取到的位置接着读取
如果设置的size大于剩余字符的数量,他会一下全部把剩余的部分读取。
file_name=‘demo.txt’
try:
#with open(file_name) as file_obj:
with open(file_name,encoding=‘utf-8’) as file_obj:
# content=file_obj.read(10)
# #content=file_obj.read(-1)
# print(content)
# print(len(content))
chunk =100
while True:
content=file_obj.read(chunk)
if not content:
break
print(content,end=’’)
print(file_obj.read())
except FileNotFoundError:
print(f’{file_name} does not exist’)
file_name=‘demo.txt’
with open(file_name,encoding=‘utf-8’) as file_obj:
#file_obj.readline() #该方法用来读取一行内容
print(file_obj.readline())
print(file_obj.readline())
#open函数来进行文件操作,默认为只读
#w 是可写的,如果文件不存在,他会帮我们来创建一个文件并写入内容
#如果文件存在则会覆盖文件内容 write只能写字符串,
其他格式需要做类型转换,write室友返回值的,返回值
就是写入字符的个数, a表示追加内容 .
file_name=‘demo3.txt’
with open(file_name,‘w’,encoding=‘utf-8’) as file_obj:
file_obj.write(‘cang jing kong’)
最后jerry老师又加了一节课,讲了单例模式和迭代器,单例模式我还是听的模模糊糊的,然后做了总复习加文章和视频分享。
这个学习群的应该是比较年轻吧,以我37岁高龄的年纪,对这些东西早已经不太感冒,我12年前,每个月的薪水都有3万人民币了,现在的我,对薪水还有什么向往呢。上次学习中文网课还是2011年吧,那时候是学的录制的视频,不是直播,没有互动。最早上网课还是从淘宝上买的新东方的盗版CET4和CET6,我记得CET4上完的时候,老师唱了一首英文的雄鹰之歌,1个月,弹指一挥间,俱往矣。
下面是这堂课的代码:
file_name=‘demo5.txt’
with open(file_name,‘x’,encoding=‘utf-8’) as file_obj:
file_obj.write(‘nba\n’)
file_name=r’E:\music\english song\01.mp3’
with open(file_name,‘rb’) as file_obj:
#print(file_obj.read(100))
#定义一个文件的新name
new_name=‘abc.mp3’
with open(new_name,‘wb’) as new_obj:
chuck=1024*100
while True:
#从已有的文件读取内容
content=file_obj.read(chuck)
#内容读取完毕,循环结束
if not content:
break
new_obj.write(content)
#迭代,就是在一些元素中获取元素的过程
#可迭代: 可迭代对象 1生成器 2 列表,元组
#迭代器,他是一个可以记住遍历位置的对象。
迭代器对象从序列中一个元素.开始访问,直到所有的元素
被访问完结束,而且只能往前不能往后
可以被next()函数调用并不断返回下一个值的对象
我们称之为迭代器iterator
生成器是可迭代的,单不是迭代器。
from collections import Iterable
lst=[1,2,3,4]
# s=(x+1 for x in range(5))
# print(isinstance(lst,Iterable))
# print(isinstance(‘lstmkasgoiahig’,Iterable))
# print(isinstance(12233,Iterable))
# print(isinstance(s,Iterable))
#创造生成器,通过列表推导式或者通过yield
lst=iter(lst)
print(next(lst))
print(next(lst))
print(next(lst))
print(next(lst))
#单例模式是设计模式的一种
#功能开发-优化
#谁创建了对象?person类的父类是object继承object
#object 有一个new方法来创建对象,
创建对象之后才可以执行init。进行初始化 。
class Person:
def new(cls, *args, **kwargs):
print(123)
def init(self):
print(‘method’)
p1=Person()
class Person:
#私有变量
_instance=None
def new(cls, *args, **kwargs):
print(123)
if Person._instance is None:
obj=object.new(cls)
Person._instance=obj
return Person._instance
return obj
def __init__(self):
print('创建完对象之后再初始化')
p1=Person()
p2=Person()
p3=Person()
print(id(p1),id(p2),id(p3))