日期: 2021 年 4 月 7 日

有办法用国外服务器做在线视频,面对国内用户吗?

国内服务器价格昂贵,难以承受。美国和欧洲服务器则相对便宜,尤其是欧洲服务器通常不限流量。但是,回国时速度明显变慢。有没有办法在国内用户的情况下使用欧洲或美国服务器观看在线视频呢?听说可以使用各种节点或者搭建跳板,但速度是否理想?投入是否过大?请教各位大神,谢谢!

不建议尝试这种方式,因为即使速度理想,像优酷、土豆、爱奇艺等视频平台早就有应对措施。选择欧美服务器省钱,但为了获得良好速度需要额外投入,可能不划算。所以,*好放弃这个想法。

此外,上传视频到YouTube,然后销售Shadowsocks(SS)账号的方式不建议,因为这会涉及到违法行为。如果您需要更快的速度,可以考虑使用阿里云香港反代,但流量费用可能较高。如果希望尝试其他方法,请考虑合法性和成本问题。

100 个网站在一台高配置的服务器好,还是放在十台低配置的服务器好

假设有 100 个网站,是放在一台高配置的服务器上好,还是放在十台每台只有那台高配置服务器的十分之一的服务器上好

flyz 1
flyz 2017-04-30 07:32:02 +08:00 via Android
不要把鸡蛋放在一个篮子里面,但是也不能太分散,50 个网站一个服务器,相互备份。
bukip 2
bukip 2017-04-30 07:54:40 +08:00
那十台能均衡吗?
gouchaoer 3
gouchaoer 2017-04-30 08:10:30 +08:00 via Android
前者,省事
eabet 4
eabet 2017-04-30 08:37:44 +08:00
@flyz @bukip @gouchaoer 会想这个问题主要是有两点。
一、分为十台服务器,那 10 个系统跟服务的开销是个问题
二、当服务器配置不是瓶颈的时候,WEB 服务器软件是不是也是个瓶颈
那两者要怎么权衡
whileFalse 5
whileFalse 2017-04-30 08:42:37 +08:00
请详细描述你的需求。
“好”这个词太宽泛了。对于楼主的问题,好这个概念包括但不限于:
– 响应速度快
– 可用性高
– 避免相互影响
– 便宜
– 易维护
而楼主所给出的条件又太宽泛了。
楼主既不能指望一个简单的答案能适用所有情况,也不能指望其他人在论坛上给出针对各种可能的详尽分析。

PS:以我的经验,凡是问出这种宽泛又比较扯淡的问题,提问者需要的基本都不是问题本身的答案。
marknote 6
marknote 2017-04-30 08:43:12 +08:00 via iPhone
不能简单的看吧。
可能需要考虑资源比如 CPU 内存带宽的消耗之类的。
eabet 7
eabet 2017-04-30 08:54:15 +08:00
@whileFalse 我只是有点迷茫= =。现在遇到的问题就是不知道服务器要怎么架构。
情况是这样的,我们平台下有差不多上百个网站,程序都一样,PHP+MYSQL 只是模板不一样。
然后这些网站吧会受攻击,所以我们自建了 CDN。
之前的话,我们是把网站都放在一台机子上,但是*近服务器开始会卡卡的了,检查了一下是 MYSQL 的问题。
所以现在要对服务器进行升级了。
就遇到了这样的问题,是要升级这个服务器的配置,还是要把这些网站分开放= =
manhere 8
manhere 2017-04-30 08:56:43 +08:00 via Android
放一起,这不就是虚拟主机商做的事嘛
vebuqi 9
vebuqi 2017-04-30 08:59:46 +08:00 via Android
当然是分开放,才好做隔离,避免相互影响
Lax 10
Lax 2017-04-30 09:27:51 +08:00
把 mysql 分开就行了。汉堡可以切成几半来吃,也可以分层吃。

whileFalse 2017-04-30 10:25:06 +08:00
@eabet 既然是 mysql 的问题,为什么不把 mysql 独立出去呢
sholmesian 12
sholmesian 2017-04-30 10:47:05 +08:00 via iPhone
@eabet 你这个情况首先应该考虑数据库分离吧,如果是类似长期不变动的企业站内容可以考虑静态化减轻数据库压力。

单台机器出故障的概率和影响较大,根据情况不妨考虑采用类似均衡负载的架构设置前端机,按照网站重要程度/资源占用率/受攻击概率/是否新上线等情况分等级设置后端机提高可用性,代价是初始化和管理相对繁琐一些。
eabet 13
eabet 2017-04-30 12:26:59 +08:00
@whileFalse 已经在着手独立了 打算用云 SQL
@sholmesian 其实就是在纠结管理起来很麻烦= =
Showfom 14
Showfom 2017-05-03 03:53:30 +08:00
开虚拟机或者 docker
qq1242245799 15
qq1242245799 2017-05-03 16:36:35 +08:00
网站有大有小,我以前一个客户开了一台香港双核 4g 的,放了 100 多个网站,数据就有 80g,不知道怎么做到的
QQ2171775959 16
QQ2171775959 2017-05-08 09:39:17 +08:00
当然是分开放好些吧,不能把所有的鸡蛋放一个篮子里。
thinkxen 17
thinkxen 2017-05-15 22:03:09 +08:00
100 个网站放一个服务器足够了~~~如果资金充裕,当然是分别放不同机房不同的线路*好了~~~
scofieldpeng 18
scofieldpeng 2017-09-13 23:07:33 +08:00
无意看到这个 4 个月之前的,我司有 2w 多个客户站点,我用了不到 10 台千万云的屌丝机依旧抗,基本也是秒开,图片那些扔 cdn, 实际上每个站点带宽也很小,做好静态化和缓存,基本没问题,对于攻击,前端架带你负载均衡跑,挂掉一个马上换一个
chinaglwo 19
chinaglwo 2017-10-18 17:35:54 +08:00
100 个网站还真不多,一个高配服务器够了的,也省事,管理也是一种*大的成本。现在都隐藏服务器 IP,前端加 cdn 或者负载均衡或 waf。当然,一定要做好异机备份。

要知道,你如果弄 10 台低配置机器,每台放 10 个网站,你能保证出现问题的时候,一台机器放 20 个网站或者更多,能否跑得动?

考虑阿里云么,可以私信我,走我的渠道,在官网下单购买,有优惠。
fengyu110122 20
fengyu110122 2018-03-26 17:59:44 +08:00
服务器服务器商靠谱,并且不打算做站群的话,放一台方便些,可用购买快照备份,加服务器配置可用对所有网站生效。
要做站群或者想利于 SEO 的话,建议多个服务器存放。但是对其备份和管理难度就相对高一些。

参考 帝通科技

你的服务器安全么?–服务器防渗透

你的服务器安全么?

1   概述

在本人所处的公司的服务器正式遭到黑客攻击之前,一直都以为 黑客 是个遥不可及的词,直到真正成为了受害者时,才猛然意识到安全的重要性。有一些基本经验和心得总结出来,和同行分享一下吧。

2   暴破手段

*粗暴的黑客行为,就是利用计算机对比人的逆天的计算能力,来暴力破解。一般的服务器都是不提供交互界面的,而且为了能够方便和其它程序进行自动化连接和集成,也是不会设置图灵测试验证码的,所以基于这种条件,服务器天然具备暴破的条件。

主要的暴破方法如下:

%title插图%num

3   资产收集

所谓的资产收集,在服务器渗透领域,就是获取服务器的域名和IP等等相关信息,这是获取渗透目标的*基本要求。资产收集的手段有很多,主要有社会工程学手段,计算机信息检索手段及混合手段。

  • 社会工程学手段

    从内部人着手,采用诱导或者收买的方式来获取信息

  • 计算机信息检索手段
    • 从社会上公开的信息进行检索分析,例如:工商信息,域名信息
  • 混合手段
    • 研究企业内部人员,观察其社交网络行为,从邮箱,QQ号等等获得信息检索的线索,逐步弄清资产

这是一个类似于“战场”的场合,其目的只有一个:获取服务器资产相关信息。

这一领域到底有多严酷,可以从以前一些“某国家研究所向国外间谍出卖重要资料*终被判死刑”的案例可以看出。当然,大部分的普通人还是没法到那个程度的,所以就从普通的技术层次来进行实验。

比如:要获取指定企业的服务器信息。

一级线索:

  • 企业名称
  • 企业网址

任何人都可以通过企业名称,可以在 启信宝 上获得此企业的详细工商信息。

例如:阿里巴巴

%title插图%num

对于小公司,特别是创业小公司来说,公司的域名一般都是以创始人或者联合创始人的名义来注册的,当然我们一般不会这个名字来查询公司域名,毕竟同名人太多,这个用于域名查询之后的验证。

一般公司肯定会有官网,有官网就有域名,通过任意的域名反查平台:

http://whois.chinaz.com/

查到相关信息如下:

  • 域名持有人姓名(可以和之前查到的企业相关人员进行验证)
  • 注册时间和到期时间
  • 电话/地址/邮箱

其实通过 电话/地址/邮箱 还可以继续进行深挖,挖到更多的线索,但是这和本文主题相关不大,略去不表。

在支持 whois反查 的平台,可以查出更多相关的域名,然后进行筛选分析得到和此企业相关的域名。

然后通过PING或者traceroute等等网络工具,可以查到服务器的具体IP地址及网络节点图。

当然,如果是自己内部人员做渗透测试,就没有这么麻烦了,直接找运维人员要一份 服务器资产清单 即可。

4   端口扫描

在获得 服务器资产清单 之后,就可以对服务器上运行的服务进行扫描。基本上所有的服务器都是以 IP+端口 作为服务地址来对外提供服务的。

通过常见的 nmap 等等工具可以扫描到服务器上暴露的端口,下面对内网的某个安全测试服务器进行扫描:

%title插图%num

显然,服务器上面运行了哪些服务一目了然。

  • ftp
  • ssh
  • dnsmasq
  • web-http
  • mongodb服务器
  • mysql
  • redis
  • 其它

有了这些信息之后,可做的事情又多了:

  • ssh密码暴破

    估计很多小白用户的root账号密码都会中招,如果这一层被攻破,服务器就成了 肉机,所以操作及文件系统权限都被获取

  • ftp密码暴破
    • 匿名登录账号会中招
    • 简单密码账号会中招

    可以查看ftp上的文件,甚至有些没有设置好权限的,还能通过此端口获取整个服务器根目录权限

  • web密码暴破

    如果获取成功,再有web权限的疏忽,则可能通过web后台上传可执行文件,执行shell脚本,间接获取服务器所有权限

  • 数据库密码暴破

    暴破破功后,影响也是相当大的

一般情况下:

  • 没经验的开发人员没有系统的安全意识,服务器漏洞百出
  • 公司用于测试的服务器,没有足够的安全意识和投入,往往成为了突破口

基于如上获取的信息,就可以对很多服务器形成很好的渗透了。因为这个世界上有太多的人还没有足够的安全意识,就已经敢把自己的服务放在公网上了。

5   预防措施

服务器 端口扫描 这一行为,*好的方法,就是尽量伪装好自己的服务器上的服务。主要手段有:

  • 禁用ICMP,防止别人通过网络工具获取网络拓扑图
  • 局域网的多台服务器之间禁止公网IP访问
  • 没有必要对外公开的信息就不要给外界权限访问
  • 对外尽量使用代向代理,不要暴露过多端口信息

当然,肯定会有很多开发小白会觉得这样很不方便,特别是在很多创业公司里面,早期如果在安全上下太多功夫,而把本来用于产品开发的保贵人力放在这边,有点不划算,这是普遍的早期企业的矛盾之处。

所以会存在这样的诉求:

  • 既要开发服务器隐藏端口
  • 也需要开发人员在自己机器上访问到相应的数据库,方便查看数据开发调试

本文提出了一种中间代理模式,来实现以上诉求。

5.1   生产配置图

一般的web应用程序都有数据库服务器和web应用服务器,还有一台反向代理服务器(nginx),如下图:

%title插图%num

其中:

  • Web服务器通过内网IP及端口连接数据库服务器
  • Nginx服务器通过内网IP及端口连接Web服务器
  • 只有80端口的Web服务暴露给客户访问

整体来说:不需要对外的服务器都对公网形成了很好的隔离。

5.2   开发配置图

对于开发调试阶段需要连接公网服务器的数据库时,可以使用如下模式:

%title插图%num

5.3   方法总结

上面的 端口映射 方法,其思想都是基于 代理映射 。即都会使用一个中间人做传话,内部的系统对外都是黑盒状态,然后安全人员集中精力守住门口即可,毕竟守门的难度比守个方圆十公里的大庄园要简单得多,真的是省时省心省力。

类似的方法在ssh登录管理服务器的时候,也有用到:开发人员要登录集群的其它服务器,必需要登录到某一台中间服务器,然后再通过中间服务器对其它服务器内网访问。

毕竟:隐藏得越深,往往就越安全也越省事。即使技术十分精湛,也没有必要去自找麻烦吧。

6   小结

上面提到的那些知识,对于专门做安全行业的人来说,估计是太自然不过的知识储备了。本文提到的这些渗透手段,主要目的是根据提出一些服务器部署的安全建议,给开发人员一些警示:尽量能够养成良好的开发习惯,做到防患于未然。

本文只是开篇,只针对服务器 端口扫描 这一行为提出了一种 端口伪装 的可行方法,后续还会出一些专题:

  • 密码暴破的预防
  • 服务器权限控制,预防小漏洞导致大问题
  • 其它

警告:本文提供的一些思路和方法仅用于学习和内部的渗透测试,千万不要用于攻击外部的服务器,否则会被法律所追究,后果自负。

print()函数

Python:print()函数

Python版本:3.8.8
目录
引入
一、print()函数详解
二、print()的格式化输出
2.1 格式控制符
引入
>>> print(“Hello World”)
Hello World

这是我初学者写的*个Python程序,这个程序的主体由一个函数组成,这个函数的函数名是print(打印),顾名思义,这个函数的作用将程序运行的结果以字符串输出,让用户/其他程序可见可读。本文将就print()函数进行系统解说

一、print()函数详解
首先,我们来看看Python自己是怎么解释print()函数的,在IDLE中输入

>>> help(print)

Python会给出如下反馈

Help on built-in function print in module builtins:

print(…)
print(value, …, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.

这段文字给了我们print()函数的一些基本信息:

built-in function print in module builtins表示print()是Python的69个内置函数之一,也就是说,使用print()函数不需要导入任何模块
print(value, …, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)展示了print()函数运行所需要的全部5个参数:value、sep、end、file、flush,其中
value参数是你要输出的值,可以是数字,字符串,列表,元组或者字典,多个value之间用逗号分隔
>>> outnum=1
>>> print(outnum)
1
>>> outstr=”Hello World”
>>> print(outstr)
Hello World
>>> outlis=[1,2,3,4,5]
>>> print(outlis)
[1, 2, 3, 4, 5]
>>> outtup=(5,10)
>>> print(outtup)
(5, 10)
>>> outdic={“Chinese”:90,”Math”:80}
>>> print(outdic)
{‘Chinese’: 90, ‘Math’: 80}
>>> print(outnum,outstr,outlis,outtup,outdic)
1 Hello World [1, 2, 3, 4, 5] (5, 10) {‘Chinese’: 90, ‘Math’: 80}

sep是separation(间隔)的缩写,这个参数控制在两个value之间输出的内容
比较下面代码的输出:
>>> print(1,2)
1 2
>>> print(1,2,sep=”+”)
1+2

可以看到*次输出的1和2之间有一个空格,第二次输出的1和2之间不再有空格,取而代之的是一个加号。这是由于参数sep在你调用print()函数时default a space(默认为空格),也就是说,当你没有为sep参数指定值时,Python默认给sep赋值为一个空格,即
>>> print(1,2)

是以
>>> print(1,2,sep=’ ‘)

被Python执行的
end(结尾)参数控制print()函数结尾输出的内容
同样比较下面代码的输出
print(1)
print(2)

”’
运行结果如下:

”’

print(1,end=”+”)
print(2)

”’
运行结果如下:
1+2
”’

和*次的输出相比,第二次输出的1和2并不在两行,而在一行中以加号分隔。与sep相似,参数end在你调用print()函数时default a newline(默认为换行),也就是说,当你没有为end参数指定值时,Python默认给end赋值为一个换行符,即
>>> print(“Hello World”)

是以
>>> print(“Hello World”,end=’\n’)

被Python执行的
file(文件)参数控制print()函数的输出目标,这个参数在你调用print()函数时defaults to the current sys.stdout(默认系统标准输出流,也就是输出到我们常说的控制台(console)),在你需要的时候,通过给file赋值,可以将程序运行的结果输出到指定的文件中
flush(刷新)参数控制print()函数输出过程中的缓冲区的刷新状态,默认为False,即不强制刷新缓冲区。简单来说,在你调用print()函数时,输出的字符串首先写入内存缓冲区,再从缓冲区写入文件,同时刷新缓冲区
运行如下代码:
import time
for i in range(10):
for j in range(200):
print(“.”,end=””)
print()
time.sleep(1)

会发现每隔一秒,200个.会一次性出现在屏幕上
如果将flush设置为True,强制刷新缓冲区:
import time
for i in range(10):
for j in range(200):
print(“.”,end=””,flush=True)
print()
time.sleep(1)

再次运行,每隔1秒,200个.会陆续出现在屏幕上,这说明输出的字符不再于缓冲区内等待,而是直接输出到控制台
同理,flush可以将数据即时写入文件,而不是等到close()后一并写入文件
综上所述,我们眼里的print()函数时这样的:

print(“Hello”,”World”)

而Python眼里的print()函数是这样的:

print(“Hello”,”World”,sep=’ ‘,end=’\n’,file=sys.stdout,flush=False)

通过熟练运用这些“不为人知”的参数,我们可以应对更加复杂的输出
注:

调用print()时必须先赋没有默认值的value参数,然后才能是其他有默认值的参数,对于有默认值的参数,其先后顺序没有要求,这和正常Python函数的调用一致
# right
print(“Hello World”,end=”!”,flush=False)
print(“Hello World”,flush=False,end=”!”)

# wrong

虽然file的默认参数是sys.stdout而print()本身并不需要导入模块,但是如果我们真的在程序中使用了sys.stdout,需要导入sys模块
# wrong
print(“Hello World”,file=sys.stdout)

# right
import sys
print(“Hello World”,file=sys.stdout)

二、print()的格式化输出
有的时候,单纯地把value用print()输出并不能满足我们的需要,比如以下几个例子:

# 输出变量数量多,种类复杂
print(“My name is”,name+”.”,”I’m”,age,”years old.”,”My major is”,major+”.”)
# 浮点数保留小数位数
print(round(valf,6))
# 以二进制输出整数
while(vali):
ans+=str(vali%2)
vali//=2
print(ans[::-1])

为了解决这类问题,print()为我们提供了格式化输出的功能,下面是实现格式化输出的几种方法

2.1 格式控制符
Python继承了很多C语言的特性,格式控制符便是其中之一,Python可以通过格式控制符和转换说明符来进行格式化输出,如上例用格式控制符写为

print(“My name is %s. I’m %d years old. My major is %s.”%(name,age,major))
1
可以看到,原本很多个value组成的复杂表达式变成了一个字符串,所有的变量被放在了*后,这些变量原本所在的位置被 %+字母 代替了,这就是格式控制符,而变量所在的元组叫做转换说明符,两者之间用 % 连接。变量与格式控制符之间的对应关系如下表
格式控制符 说明 格式控制符 说明
%d / %i 十进制整数(dec) %r 字符串以repr()显示
%b 二进制整数(bin) %c 单个字符(char)及其ASCII码
%o 八进制整数(oct) %f / %F 浮点数
%x / %X 十六进制整数(hex),区分大小写 %e / %E 科学计数法 ,区分大小写
%s 字符串以str()显示 %g / %G 自动匹配 十进制整数/浮点数/科学计数法

OpenCV移动物体检测

OpenCV移动物体检测

#encoding=utf-8
import cv2
import time
import winsound

camera = cv2.VideoCapture(0) # 定义摄像头对象,其参数0表示*个摄像头(自带摄像头)
if camera is None:
#如果摄像头打开失败,则输出提示信息
print(‘please connect the camera’)
exit()

fps = 30 #帧率
pre_frame = None #总是取前一帧做为背景(不用考虑环境影响)

while True:
start = time.time()
# 读取视频流
res, cur_frame = camera.read()
if res != True:
break
end = time.time()

seconds = end – start
if seconds < 1.0/fps:
time.sleep(1.0/fps – seconds)

cv2.namedWindow(‘img’,0);
#cv2.imshow(‘img’, cur_frame)

#检测如何按下Q键,则退出程序
key = cv2.waitKey(30) & 0xff
if key == 27:
break
#转灰度图
gray_img = cv2.cvtColor(cur_frame, cv2.COLOR_BGR2GRAY)
#将图片缩放
gray_img = cv2.resize(gray_img, (500, 500))
# 用高斯滤波进行模糊处理
gray_img = cv2.GaussianBlur(gray_img, (21, 21), 0)

#如果没有背景图像就将当前帧当作背景图片
if pre_frame is None:
pre_frame = gray_img
else:
# absdiff把两幅图的差的*对值输出到另一幅图上面来
img_delta = cv2.absdiff(pre_frame, gray_img)

#threshold阈值函数(原图像应该是灰度图,对像素值进行分类的阈值,当像素值高于(有时是小于)
#阈值时应该被赋予的新的像素值,阈值方法)
thresh = cv2.threshold(img_delta, 25, 255, cv2.THRESH_BINARY)[1]

#膨胀图像
thresh = cv2.dilate(thresh, None, iterations=2)

# findContours检测物体轮廓(寻找轮廓的图像,轮廓的检索模式,轮廓的近似办法)
contours, hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
#灵敏度
if cv2.contourArea(c) < 1000: # 1000为阈值
continue
else:
#框选移动部分
(x,y,w,h) = cv2.boundingRect(c)
cv2.rectangle(cur_frame,(x,y),(x+w,y+h),(0,255,0),2)

print(“something is moving!!!”)
flag = True
if flag == True:
winsound.Beep(600, 1000)
break

#显示
cv2.imshow(‘img’, cur_frame)
pre_frame = gray_img

# release()释放摄像头
camera.release()
#destroyAllWindows()关闭所有图像窗口
cv2.destroyAllWindows()

解构赋值

解构赋值

ES6学习笔记二:解构赋值
前言
一、数组解构赋值
1.基本用法
2.默认值使用
二.对象解构赋值
三.字符串解构赋值
四.数值和布尔值解构赋值
五.解构赋值的常用地方
5.1.交换两个变量的值
5.2.函数返回多个值
5.3.函数参数的定义
总结
前言
此系列文章用于记录小萌新的ES6的学习经历如有什么错误或者不好的地方请各位大佬多多指教

一、数组解构赋值
解构赋值理解起来很简单,顾名思义就是解析结构进行赋值具体怎么进行赋值呢?请看下面
其实学过ptyhon的人知道这个解构赋值其实我感觉有点模仿python的一些功能

1.基本用法
代码如下(示例):

let a = 1;
let b = 2;
let c = 3;

let [a,b,c]=[1,2,3];
1
ES6允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,该操作即为解构(Destructuring)。

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。所以两边的模式必须是一样的不然则会报错。

let [foo,[[bar], baz]]=[1,[[2],3]];
// foo=1 bar=2 baz=3
let [foo] = 1;
// TypeError: 1 is not iterable
let [x, , y] = [1, 2, 3];
// x = 1,y = 3
let [head, …tail] = [1, 2, 3, 4];
// head = 1,tail = [ 2, 3, 4 ]
let [z, n] = [1];
// z = 1,n = undefined
let [q, [w], p] = [1, [2, 3], 4];
// q = 1,w = 2,p = 4
let [q, [w], p] = [1, [2, 3], 4];
// q = 1,w = 2,p = 4

上面代码中一个,表示一个对应的值*后匹配后数组会通过下标进行匹配。
而…这个符号叫做扩展运算符他的作用放在*后可以除了前面匹配到的,把后面所有进行匹配*后返回一个数组。
如果左边的模式中有,右边赋值的模式中没有则匹配失败,变量的值就是undefined
如果右边的模式有,左边的模式没有则会忽略。
2.默认值使用
解构赋值中允许给左边变量设置默认值,以免右边不能匹配时不至于为undefined

let [x,y=5] = [3]
console.log(x,y); // 3 5
let [m, n = ‘b’] = [‘a’, undefined];
console.log(m,n); // a b
let [q, p = ‘b’] = [‘a’, null];
console.log(q,p); // a null

默认值生效必须是右边数组成员===严格等于undefined才能使默认值生效
当然如果左边变量没有匹配到数值也会是undefined会使默认值生效,上面提到过
二.对象解构赋值
对象进行解构赋值与数组不一样,它没有索引所以只能用键值来一一对应匹配。

代码如下(示例):

{
let { x, y } = { x: “aaa”, y: “bbb” };
console.log(x,y); // aaa bbb
}
{
let { x: x, y: y} = { x: 111, y: 222 };
console.log(x,y); // 111 222
}

一个代码块是简写用法。
第二个代码块首先以右边的键名去匹配左边的键名,然后再把111和222这两个值分别赋值给左边匹配好键名的值上。
同时对象解构赋值也可以设置默认值并且如果解构失败则会给左边的变量赋undefined

代码如下(示例):

{
let { x, y = 5 } = { x: 1 };
let { foo } = { bar: ‘bbb’ };
console.log(x,y,foo); // 1 5 undefined
}

注意

如果你的变量在使用解构赋值的时候已经声明了,必须在使用的时候使用括号括起来。否则会报错

代码如下(示例):

{
let x;
{ x } = { x: 1 }; // 会报错
let x;
({ x } = { x: 1 }); // x = 1
}

三.字符串解构赋值
字符串在js是一种特殊的数组所以也是按照索引进行赋值。
并且可以获取右边对象的一些属性。
代码如下(示例):

{
const [a, b, c, d] = ‘hello’;
console.log(a,b,c,d); // h e l l
let{ length: len } = ‘hello’;
console.log(len); // 5
}

四.数值和布尔值解构赋值
解构赋值的原则是,如果等号右边不是对象,则先转换为对象。
如果等号右边无法转换为对象,则会报错,如null和undefined。

代码如下(示例):

{
let { toString: s } = 123;
console.log(s.call(100));
//s===Number.prototype.toString为true
}

五.解构赋值的常用地方
5.1.交换两个变量的值
在以前js交换两个变量的值只能先创建第三个变量,然后通过第三个变量来进行交换。

而解构赋值可以轻松的解决这个问题。

代码如下(示例):

{
//以前的方法
let a = 1;
let b = 2;
let c;
c = a;
a = b;
b = c;
console.log(a,b); // 2 1

//解构赋值的方法
let x = 1, y = 3;
[x, y] = [y, x];
console.log(x,y); // 3 1
}

5.2.函数返回多个值
这个功能点python其实函数就可以直接返回多个值,而js通过解构赋值也可以返回多个值了。

代码如下(示例):

{
function func() {
return [1, 2, 3];
}
let [a, b, c] = func(); // 1,2,3
}

5.3.函数参数的定义
在函数参数接受的时候也可以使用解构赋值设置默认参数,或者使用扩展运算符…来把多出来的参数进行获取。

代码如下(示例):

{
function f([x, y=3, …z]) {
console.log(x,y,z); // 1 3 [ 3, 4 ]
}
f([1, , 3, 4]);
}

总结
以上就是ES6的解构赋值。

用Python画简易昆工图书馆

用Python画简易昆工图书馆

用Python画简易昆工图书馆
这个学期在学Python,于是就画了学校的图书馆,比较简单。
各位可以先看看成品。

%title插图%num
代码写的很冗长,只用#做了简单的注释分组,但也没分的很详细,单纯就是想画一下。

#coding=UTF-8
import turtle as t
t.pencolor(“black”)
t.speed(10)
#地线
t.up()
t.goto(-650,-300)
t.down()
t.forward(1300)
#主门
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(-250,-300)
t.down()
t.seth(90)
t.forward(410)
t.right(90)
t.forward(500)
t.right(90)
t.forward(410)
t.right(90)
t.forward(90)
t.right(90)
t.forward(300)
t.left(90)
t.forward(90)
t.left(90)
t.forward(300)
t.right(90)
t.forward(20)
t.right(90)
t.forward(300)
t.left(90)
t.forward(100)
t.left(90)
t.forward(300)
t.right(90)
t.forward(20)
t.right(90)
t.forward(300)
t.left(90)
t.forward(90)
t.left(90)
t.forward(300)
t.right(90)
t.forward(90)
t.end_fill()
#门楣
t.fillcolor(“#fffcf4”)
t.begin_fill()
t.up()
t.goto(-160,-300)
t.down()
t.right(90)
t.forward(300)
t.right(90)
t.forward(90)
t.right(90)
t.forward(50)
t.right(90)
t.forward(50)
t.left(90)
t.forward(250)
t.right(90)
t.forward(40)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-50,0)
t.down()
t.left(180)
t.forward(100)
t.right(90)
t.forward(50)
t.right(90)
t.forward(100)
t.right(90)
t.forward(50)
t.end_fill()
t.begin_fill()
t.up()
t.goto(70,0)
t.down()
t.right(90)
t.forward(90)
t.right(90)
t.forward(300)
t.right(90)
t.forward(40)
t.right(90)
t.forward(250)
t.left(90)
t.forward(50)
t.right(90)
t.forward(50)
t.end_fill()
#门洞
t.fillcolor(“black”)
t.begin_fill()
t.up()
t.goto(-120,-300)
t.down()
for i in range (2):
t.forward(250)
t.right(90)
t.forward(50)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-50,-300)
t.down()
for i in range (2):
t.forward(250)
t.right(90)
t.forward(100)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(70,-300)
t.down()
for i in range (2):
t.forward(250)
t.right(90)
t.forward(50)
t.right(90)
t.end_fill()
#左侧门洞带玻璃
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(-530,-300)
t.down()
for i in range (2):
t.forward(210)
t.right(90)
t.forward(70)
t.right(90)
t.end_fill()
t.fillcolor(“#bab9b6”)
t.begin_fill()
t.up()
t.goto(-460,-300)
t.down()
for i in range (2):
t.forward(150)
t.right(90)
t.forward(25)
t.right(90)
t.up()
t.goto(-435,-300)
t.down()
for i in range (2):
t.forward(150)
t.right(90)
t.forward(25)
t.right(90)
t.end_fill()
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(-460,-150)
t.goto(-460,-90)
t.goto(-410,-110)
t.goto(-410,-150)
t.goto(-460,-150)
t.down()
t.end_fill()
t.forward(60)
t.right(113)
t.forward(60)
t.fillcolor(“#dddad9”)
t.begin_fill()
t.up()
t.goto(-410,-300)
t.down()
t.left(113)
for i in range (2):
t.forward(240)
t.right(90)
t.forward(30)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-380,-300)
t.down()
for i in range (2):
t.forward(240)
t.right(90)
t.forward(40)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-340,-300)
t.down()
for i in range (2):
t.forward(240)
t.right(90)
t.forward(60)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-280,-300)
t.down()
for i in range (2):
t.forward(240)
t.right(90)
t.forward(30)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-330,-60)
t.down()
for i in range (2):
t.forward(150)
t.right(90)
t.forward(15)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-315,-60)
t.down()
for i in range (2):
t.forward(150)
t.right(90)
t.forward(40)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-275,-60)
t.down()
for i in range (2):
t.forward(150)
t.right(90)
t.forward(25)
t.right(90)
t.end_fill()
#右侧门洞带玻璃
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(530,-300)
t.down()
for i in range (2):
t.forward(210)
t.left(90)
t.forward(70)
t.left(90)
t.end_fill()
t.fillcolor(“#bab9b6”)
t.begin_fill()
t.up()
t.goto(460,-300)
t.down()
for i in range (2):
t.forward(150)
t.left(90)
t.forward(25)
t.left(90)
t.up()
t.goto(435,-300)
t.down()
for i in range (2):
t.forward(150)
t.left(90)
t.forward(25)
t.left(90)
t.end_fill()
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(460,-150)
t.goto(460,-90)
t.goto(410,-110)
t.goto(410,-150)
t.goto(460,-150)
t.down()
t.end_fill()
t.forward(60)
t.left(113)
t.forward(60)
t.fillcolor(“#dddad9”)
t.begin_fill()
t.up()
t.goto(410,-300)
t.down()
t.right(113)
for i in range (2):
t.forward(240)
t.left(90)
t.forward(30)
t.left(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(380,-300)
t.down()
for i in range (2):
t.forward(240)
t.left(90)
t.forward(40)
t.left(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(340,-300)
t.down()
for i in range (2):
t.forward(240)
t.left(90)
t.forward(60)
t.left(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(280,-300)
t.down()
for i in range (2):
t.forward(240)
t.left(90)
t.forward(30)
t.left(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(330,-60)
t.down()
for i in range (2):
t.forward(150)
t.left(90)
t.forward(15)
t.left(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(315,-60)
t.down()
for i in range (2):
t.forward(150)
t.left(90)
t.forward(40)
t.left(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(275,-60)
t.down()
for i in range (2):
t.forward(150)
t.left(90)
t.forward(25)
t.left(90)
t.end_fill()
#顶部
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(-160,110)
t.down()
for i in range (2):
t.forward(100)
t.right(90)
t.forward(60)
t.right(90)
t.end_fill()
t.fillcolor(“#dddad9”)
t.begin_fill()
t.up()
t.goto(-100,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(20)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-80,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(33)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-47,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(30)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(-17,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(34)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(17,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(30)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(47,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(33)
t.right(90)
t.end_fill()
t.begin_fill()
t.up()
t.goto(80,110)
t.down()
for i in range (2):
t.forward(140)
t.right(90)
t.forward(20)
t.right(90)
t.end_fill()
t.fillcolor(“#ab7c65”)
t.begin_fill()
t.up()
t.goto(100,110)
t.down()
for i in range (2):
t.forward(100)
t.right(90)
t.forward(60)
t.right(90)
t.end_fill()
t.hideturtle()
t.done()

 

lambda阻碍子窗口进程?

PyQt5: lambda阻碍子窗口进程?

PyQt5: lambda阻碍子窗口进程?
通常而言,调用QDialog子窗口时,仅使用show()而不配合exec()或添加self.时将导致子窗口“一闪而过”。

但我近期发现,如果子窗口中存在lambda表达式时,则不存在子窗口闪退的现象。

父窗口代码:

class MainWindow(QMainWindow):
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle(‘父窗口’)
self.button1.clicked.connect(self.action1)

def action1(self):
self.textline1.setText(str(data1))
print(data1)
print(‘打开子窗口’)
subwindow = subWindow.subDialog(data1)
subwindow.show()
# 接受信号
subwindow.Signal1.connect(self.getConstants1)

if __name__ == ‘__main__’:
app = QApplication(sys.argv)
UI = MainWindow()
UI.resize(600,800)
UI.show()
sys.exit(app.exec())

子窗口代码

class subDialog(QDialog):
Signal1 = pyqtSignal(list)
Signal2 = pyqtSignal(str)
def __init__(self, data):
super(subDialog, self).__init__()
self.setWindowTitle(‘子窗口’)
self.button1.clicked.connect(lambda: self.action1(data))
self.button2.clicked.connect(self.action2)

def action1(self, data):
print(data)
return

if __name__ == ‘__main__’:
data1 = [56,5,6,5,2,5,56]
data2 = ‘85646555’
app = QApplication(sys.argv)
# UI = subDialog(data1)
UI = subDialog(data2)
UI.resize(600,800)
UI.show()
sys.exit(app.exec())

暂不清楚原因

用Python完成购物车的简单操作

用Python完成购物车的简单操作

用Python完成购物车的简单操作
两层循环遍历
化简版
b站python爬虫课程里的作业。

两层循环遍历
当时的想法就是用两遍循环遍历循环二维数组,优点是有结构感。

# -*- coding = utf-8 -*-
# @Time : 2021/4/5 18:50
# @Author : Hypocrisy.
# @File : homework.py
# @Software : PyCharm

sc = 0
product = [[“iphone”, 6888], [“MacPro”, 14800], [“小米6”, 2499], [“Coffee”, 31], [“Book”, 60], [“Nike”, 699]]
print(“-“*12, “商品列表”, “-“*12)
i = 0 # 用于商品序列
for pro in product:
print(i, “\t\t”, end=”\t”) # 打印序号
for pro1 in product[i]:
print(pro1, “\t\t”, end=”\t”) # 打印商品中的所有项目
i += 1
if i <= len(product):
print()
sc = input(“请输入商品序号加入购物车(输入q退出并打印购物车列表):”)
List = []
while sc != “q”:
List.append(product[int(sc)])
sc = input(“请输入商品序号加入购物车(输入q退出并打印购物车列表):”)
print(“-“*12, “购物车列表”, “-“*12)
i = 0
money = 0
for pro in List: # 循环遍历列表,统计金额
print(i, “\t\t”, end=”\t”)
for pro1 in List[i]:
if type(pro1) == int:
money += pro1
print(pro1, “\t\t”, end=”\t”)
i += 1
if i <= len(List):
print()
print(“总金额:”, money, “件数:”, i)

化简版
利用已知商品格式,直接用二维数组,定点输出,代码可以少一些

# -*- coding = utf-8 -*-
# @Time : 2021/4/5 19:51
# @Author : Hypocrisy.
# @File : test.py
# @Software : PyCharm

sc = 0
product = [[“iphone”, 6888], [“MacPro”, 14800], [“小米6”, 2499], [“Coffee”, 31], [“Book”, 60], [“Nike”, 699]]
print(“————商品列表————“)
i = 0 # 用于商品序列
for pro in product:
print(i, “\t\t”, end=”\t”) # 打印序号
print(product[i][0], “\t\t”, product[i][1]) # 打印商品中的所有项目
i += 1
sc = input(“请输入商品序号加入购物车(输入q退出并打印购物车列表):”)
List = []
while sc != “q”:
List.append(product[int(sc)])
sc = input(“请输入商品序号加入购物车(输入q退出并打印购物车列表):”)
i = 0
money = 0
print(“你购买的商品有:”, end=””)
for pro in List:
money += List[i][1]
print(List[i][0], end=”、”)
i += 1
print(“总金额:”, money, “件数:”, i)

Django 非项目文件导包失败

Django 非项目文件导包失败

错误介绍
在django项目中,当你从非项目文件夹导包时,在终端运行该文件报无该模块时,是否很困惑,因为当你直接重编辑器pycharm运行又是正常的。

错误情况
from xxx import xx

ModuleNotFoundError: No module named “xxx”

错误原因
直接导非项目文件里的包,在没有设置环境路径的情况下,在终端运行时,是找不到该路径下的文件夹的,需要先将文件夹加入系统环境路径中。

解决错误
import sys
import os

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)

## 开始导入你需要的包

解决Django中直接脚本运行并可以操作模型
import sys
import os
import django
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
os.environ.setdefault(“DJANGO_SETTINGS_MODULE”, “xxxx.settings”)
django.setup()

### 可以开始为所欲为了。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速