python学习
day1
turtle pos()获取位置,获得的是一个元组,可以通过索引获取x y值
使用sqrt要import math,然后math.sqrt
也可以from math import sqrt 就能直接使用sqrt了
day3
厘米和英尺转换可以添加上break但还存在问题,后期解决(已解决)
个人所得税的算法,可理解可不理解
print('对应的等级是:', grade) print可以这么串联,因为grade是字符串,若是数字则需要print('对应的等级是:', str(grade))
shift+tab删除多行的tab
day4
判断输入字符类型存疑,后续解决
day6
def is_prime(num):
for factor in range(2, num):
if num % factor == 0:
return False
return True if num != 1 else False
最后一行存疑
再看看下面这段代码,我们希望通过函数调用修改全局变量a
的值,但实际上下面的代码是做不到的。
def foo():
a = 200
print(a) # 200
if __name__ == '__main__':
a = 100
foo()
print(a) # 100
在调用foo
函数后,我们发现a
的值仍然是100,这是因为当我们在函数foo
中写a = 200
的时候,是重新定义了一个名字为a
的局部变量,它跟全局作用域的a
并不是同一个变量,因为局部作用域中有了自己的变量a
,因此foo
函数不再搜索全局作用域中的a
。如果我们希望在foo
函数中修改全局作用域中的a
,代码如下所示。
def foo():
global a
a = 200
print(a) # 200
if __name__ == '__main__':
a = 100
foo()
print(a) # 200
我们可以使用global
关键字来指示foo
函数中的变量a
来自于全局作用域,如果全局作用域中没有a
,那么下面一行的代码就会定义变量a
并将其置于全局作用域。同理,如果我们希望函数内部的函数能够修改嵌套作用域中的变量,可以使用nonlocal
关键字来指示变量来自于嵌套作用域,请大家自行试验。
需要理解
day7
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
yield a ------------此处print(a) 运行fib(20)会生成前20 个数 若return a 运行fib(20)结果为1
def main():
for val in fib(20):
print(val)
if __name__ == '__main__':
main()
-----------------------------------------------
return 语句就是讲结果返回到调用的地方,并把程序的控制权一起返回
程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return。
----------------------------------------------------
import sys
def main():
f = [x for x in range(1, 10)]
print(f)
f = [x + y for x in 'ABCDE' for y in '1234567']
print(f)
# 用列表的生成表达式语法创建列表容器
# 用这种语法创建列表之后元素已经准备就绪所以需要耗费较多的内存空间
f = [x ** 2 for x in range(1, 1000)]
print(sys.getsizeof(f)) # 查看对象占用内存的字节数----------------9024
print(f)--------------[1,4,9............]列表
# 请注意下面的代码创建的不是一个列表而是一个生成器对象
# 通过生成器可以获取到数据但它不占用额外的空间存储数据
# 每次需要数据的时候就通过内部的运算得到数据(需要花费额外的时间)
f = (x ** 2 for x in range(1, 1000))
print(sys.getsizeof(f)) # 相比生成式生成器不占用存储数据的空间---------------120
print(f) ------------------------<generator object main.<locals>.<genexpr> at 0x000001CD8754BC00>
for val in f:
print(val) --------------1 4 9.............
if __name__ == '__main__':
main()
----------------------------------------------------------
----------------------------------------------------------
time.sleep(t) t -- 推迟执行的秒数
-------------------------------------------------------
randint(0,n) 随机选取0~n之间的数
randint(a,b) == randrange(a,b+1)
----------------------------------------------
使用random模块的sample函数来实现从列表中选择不重复的n个元素
-------------------------------------------
sort()方法是在原来的列表上直接进行排序,并没有返回一个新的列表,所以返回值为None!
sorted()函数排好序后会返回一个新的列表,原来的列表并没有发生改变!
---------------------------------------------------------------------------------------------
2是宽度 如果整数不够2列就补上0
printf("%02d" ,3);-------03
如果大于2没有影响 printf("%02d",1234);----------1234
--------------------------------------------------------------------------
基督徒问题还需要再思考
day8~9
实例不能访问私有变量
import math
class point(object):
def __init__(self,x=0,y=0):
self.x = x
self.y = y
def move_to(self,x,y):
self.x = x
self.y = y
def move_by(self,dx,dy):
self.x += dx
self.y += dy
print(dx,dy,"555")
def distance_to(self,other):
dx = self.x - other.x
dy = self.y - other.y
print(other.x,other.y,self.x,self.y,"666")
return math.sqrt(dx**2 + dy**2)
def __str__(self):
return "{},{}".format(str(self.x),str(self.y))
def main():
p1 = point(3,5)
p2 = point()
print(p1,p2)
p2.move_by(-1,2)
print(p2)
print(p1.distance_to(p2))
if __name__ == "__main__":
main()
-------------------------------------------------------------------------------------------------
Python 中的属性访问与描述符
https://blog.csdn.net/lilong117194/article/details/80111803
属性在哪个对象上定义,便会出现在哪个对象的__dict__
中
-------------------------------------
@staticmethod@classmethod
https://zhuanlan.zhihu.com/p/28010894
----------------------------------------------------------------------------------------
有了init方法,在创建实例的时候,就不能传入空的参数了,必须传入与init方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去
-
__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。
-
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
-
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
能用type()
判断的基本类型也可以用isinstance()
判断
配合getattr()
、setattr()
以及hasattr()
,我们可以直接操作一个对象的状态
getattr(obj, 'x') ==
obj.x
------------------------------------------------------------------------
在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性
https://www.liaoxuefeng.com/wiki/1016959663602400/1017594591051072
------------------------------------------------------------------
s.name = 'Michael' # 动态给实例绑定一个属性
s1.set_age=MethodType(set_age,s1,Student)#第一个参数是要绑定的方法,第二个参数是要绑定的对象,第三个参数是类名(可省略)
为了给所有实例都绑定方法,可以给class绑定方法:
>>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = set_score
或
Student.set_age=MethodType(set_age,Student)
------------------------------------------------------
lambda 参数:操作(参数)
filter(function, iterable)
- function -- 判断函数。
- iterable -- 可迭代对象。
-------------------------------------
若a为list,b=a,改变b时a也会改变
可用b = list(a)或b = a[:],改变b时a不变
---------------------------------------------
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
https://foofish.net/python-closure.html
-------------------------------------------------
函数内部的变量名如果第一次出现,且出现在=前面,即被视为定义一个局部变量
这里会报错
函数内部的变量名如果第一次出现,且出现在=后面,且该变量在全局域中已定义,则这里将引用全局变量,如果该变量在全局域中没有定义,当然会出现“变量未定义”的错误。
函数中使用某个变量时,该变量名既有全局变量也有同名的局部变量,则会使用局部变量
在函数中,如果想给全局变量赋值,则需要用关键字global
https://blog.csdn.net/dongtingzhizi/article/details/8973569
----------------------------------
在def里面global的变量只能在def里面/def下面的def里面使用,不能在全局里面使用
ef add_b():
global b
b = 42
def do_global():
global b
b = 10
print(b)
do_global()
print(b)
# print(b) ---------------------------在这里会报错 (因为不是全局变量??)
add_b()
print(b) ------------------这里不会
https://blog.csdn.net/youngbit007/article/details/64905070
-------------------------------------------------------------------------
Python不会为‘类名’的实例对象实例化一个绑定方法,绑定方法也是对象,会产生开销,静态方法可以避免这类情况
https://zhuanlan.zhihu.com/p/51036130
----------------------------------------------------------------
__new__
作为构造器,起创建一个类实例的作用。而__init__
作为初始化器,起初始化一个已被创建的实例的作用。
__new__
是用来创造一个类的实例的,而__init__
是用来初始化一个实例的
__new__所接收的第一个参数是cls,而__init__所接收的第一个参数是self。这是因为当我们调用__new__的时候,该类的实例还并不存在(也就是self所引用的对象还不存在),所以需要接收一个类作为参数,从而产生一个实例。而当我们调用__init__的时候,实例已经存在,因此__init__接受self作为第一个参数并对该实例进行必要的初始化操作。这也意味着__init__是在__new__之后被调用的。
__init__有return时会报错
__new__方法用于创建对象并返回对象,当返回对象时会自动调用__init__方法进行初始化。__new__方法是静态方法,而__init__是实例方法。