unless相关知识
-
Python 小目标4Python Day 10 Leap Year I have a friend Cindy, she was actually born on Feb.29th, and I remember we celebrated her birthday together 2012 in the Maths place! Leap Year was adapted in Gregorian Calendar. There are Three Criteria: The year can be evenly divided by 4, is a leap year, unless: The year can be evenly divided by 100, it is NOT a leap year, unless: The year is also evenly d
-
用HTTP/Post与WCF互操作WCF does not support raw HTTP requests with the content-type 'application/x-www-form-urlencoded' (which is the content-type the browser sends when you hit 'submit' in a <form> element) out of the box unless you treat the request body as a Stream.This makes sense if you consider that the same principle applies when returning data, as you can see here in the Picture Services sample, both the GetDocumentation() and GetPicture() oper
-
安装nginx+mysql+php+php-fastcgi一、更改yum源为网易的源加快速度vi /etc/yum.repos.d/CentOS-Base.repo更改内容如下1. # CentOS-Base.repo2. #3. # This file uses a new mirrorlist system developed by Lance Davis forCentOS.4. # The mirror system uses the connecting IP address of the client and the5. # update status of each mirror to pick mirrors that are updated to and6. # geographically close to the client. You should use this for CentOS updates7. # unless you are manually picking other mirrors.8. #9. # If t
-
Mac安装Pillow模块解决办法Mac Python上安装Pillow报错: ValueError: jpeg is required unless explicitly disabled using 问题原因: 这是因为在Pillow3.0以上的版本中libjpeg和zlib是必不可少的。安装这两个库后,Pillow便可正常安装。 http://stackoverflow.com/questions/34631806/fail-during-installation-of-pillow-python-module-in-linux 解决步骤: 打开终端窗口, 粘贴以下脚本。安装brew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/inst
unless相关课程
unless相关教程
- 1. if… 语句 if... 语句是条件语句中最基本的,当 if 后的条件表达式得到满足的时候,执行代码部分,不满足条件的时候,代码将被忽略。实例:if 10 < 20 then puts "10 is less than 20"end# ---- 输出结果 ----10 is less than 20解释:在执行时,代码将显示字符串“10 is less than 20”,因为 10 < 20 表达式的计算结果为true。end语句标志着if语句的结束。经验:在实际开发中我们常常省略 then,得到的结果是相同的。实例:if 10 < 20 puts "10 is less than 20"end# ---- 输出结果 ----10 is less than 20另外,我们还可以将 if 语句的判断部分后置,这叫做条件后置:实例:puts "10 is less than 20" if 10 < 20# ---- 输出结果 ----10 is less than 20if 后面的条件表达式可以使用逻辑运算符。实例:firstname = 'john'lastname = "smith"if firstname == "john" && lastname == "smith" puts "Hello John!"end# ---- 输出结果 ----Hello John!还有一种跟 if 相反的判断,名叫 unless,它和 if 刚好相反,当 unless 后面的条件不满足的时候,才执行代码部分。实例:unless 10 >= 20 puts "10 not bigger than or equal 20"end# ---- 输出结果 ----10 not bigger than or equal 20注意事项:unless 也可以称为 if not,因为很容易让人混淆,所以我们尽量不使用它。
- 1.5 增加校验属性的Block 让方法对传入的Block值进行校验class Personenddef add_checked_attribute(klass, attribute, &validation) klass.class_eval do define_method "#{attribute}=" do |value| raise 'Invalid attribute!' unless validation.call(value) instance_variable_set("@#{attribute}", value) end define_method attribute do instance_variable_get "@#{attribute}" end endendadd_checked_attribute(Person, :age) {|age| age >= 18}add_checked_attribute(Person, :sex) {|age| age == 'man'}me = Person.newme.age = 18me.sex = 'man'puts me.ageputs me.sex# ---- 输出结果 ----18man当我们赋予属性的值不满足条件的时候会抛出异常。me = Person.newme.sex = 'woman'# ---- 输出结果 ----Invalid attribute! (RuntimeError)
- 1.6 最后将方法定义到模块,完成类宏 我们在引入类宏的模块的时候使用的是include,所以我们使用included钩子方法,在钩子方法对引用的类进行extend(因为extend模块添加类方法),替代之前的class_eval,将之前定义属性的方法定义到被extend的模块中,从而使定义的方法可以被类调用(类方法)。# 定义模块部分module CheckedAttributes def self.included(klass) klass.extend ClassMethods endendmodule ClassMethods def attr_checked(attribute, &validation) define_method "#{attribute}=" do |value| raise 'Invalid attribute!' unless validation.call(value) instance_variable_set("@#{attribute}", value) end define_method attribute do instance_variable_get "@#{attribute}" end endend# 引用部分class Person include CheckedAttributes attr_checked :age {|age| age >= 18} attr_checked :sex {|sex| sex == 'man'}endme = Person.newme.age = 18me.sex = 'man'puts me.ageputs me.sex# ---- 输出结果 ----18man当我们赋予属性的值不满足条件的时候同样会抛出异常。me = Person.newme.age = 10# ---- 输出结果 ----Invalid attribute! (RuntimeError)
- 2. raise抛出异常 除了编程异常出现的异常外,我们可以使用raise来强制抛出一个异常。实例:def raise_exception puts "before raise exception" raise "This is a exception" puts "after raise exception"endraise_exception# ---- 输出结果 ----before raise exceptionTraceback (most recent call last): 1: from test.rb:7:in `<main>'test.rb:3:in `raise_exception': This is a exception (RuntimeError)解释:由打印我们可以看到,当执行完"before raise exception"的文字输出后,程序抛出了一个异常,这个异常的名称是我们定义的“This is a exception”。Tips:默认情况下,raise创建RuntimeError类的异常。我们也可以通过传入异常的类型,来改变raise异常的类型。实例:def inverse(x) raise ArgumentError, 'Argument is not numeric' unless x.is_a? Numeric 1.0 / x end puts inverse(2) puts inverse('not a number') # ---- 输出结果 ----0.5Traceback (most recent call last): 1: from test.rb:6:in `<main>'test.rb:2:in `inverse': Argument is not numeric (ArgumentError)解释: 我们在raise后面增加了需要抛出的异常类型,由输出结果我们可以看到,最后抛出的异常类型为ArgumentError。
- 2. 使用 JConsole 监控 Zookeeper JConsole 是 JDK 自带的 Java 进程监控工具,Zookeeper 是基于 Java 的应用程序,也支持 JMX( Java Management Extensions ),所以我们可以通过 JConsole 来对 Zookeeper 的运行状态进行监控。在使用 JConsole 开启监控之前,我们需要修改 Zookeeper 关于 JMX 的配置。如果是 Windows 平台的需要修改启动文件 zkServer.cmd,如果是 Linux 平台则需要修改启动文件 zkServer.sh。Windows 平台修改 zkServer.cmd在 call %JAVA% 这一行中加入以下配置:# 对 jmx 开放的端口,要注意避免和其它端口冲突"-Dcom.sun.management.jmxremote.port=21810"# 关闭 ssl"-Dcom.sun.management.jmxremote.ssl=false"# 关闭身份验证"-Dcom.sun.management.jmxremote.authenticate=false"zkServer.cmd 完整的配置如下:@echo offREM Licensed to the Apache Software Foundation (ASF) under one or moreREM contributor license agreements. See the NOTICE file distributed withREM this work for additional information regarding copyright ownership.REM The ASF licenses this file to You under the Apache License, Version 2.0REM (the "License"); you may not use this file except in compliance withREM the License. You may obtain a copy of the License atREMREM http://www.apache.org/licenses/LICENSE-2.0REMREM Unless required by applicable law or agreed to in writing, softwareREM distributed under the License is distributed on an "AS IS" BASIS,REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.REM See the License for the specific language governing permissions andREM limitations under the License.setlocalcall "%~dp0zkEnv.cmd"set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMainset ZOO_LOG_FILE=zookeeper-%USERNAME%-server-%COMPUTERNAME%.logecho oncall %JAVA% "-Dcom.sun.management.jmxremote.port=21810" "-Dcom.sun.management.jmxremote.ssl=false" "-Dcom.sun.management.jmxremote.authenticate=false" "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" "-Dzookeeper.log.file=%ZOO_LOG_FILE%" "-XX:+HeapDumpOnOutOfMemoryError" "-XX:OnOutOfMemoryError=cmd /c taskkill /pid %%%%p /t /f" -cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %*endlocal Linux 平台修改 zkServer.sh在第一个 ZOOMAIN 中添加以下配置:# 关闭仅本地连接-Dcom.sun.management.jmxremote.local.only=false# zookeeper地址-Djava.rmi.server.hostname=127.0.0.1 # 对 jmx 开放的端口,要注意避免和其它端口冲突-Dcom.sun.management.jmxremote.port=21810 # 关闭 ssl-Dcom.sun.management.jmxremote.ssl=false # 关闭身份验证-Dcom.sun.management.jmxremote.authenticate=false # 开启日志-Dzookeeper.jmx.log4j.disable=true添加完毕后第一个 ZOOMAIN 配置如下:ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=21810 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dzookeeper.jmx.log4j.disable=true org.apache.zookeeper.server.quorum.QuorumPeerMain"配置完启动文件,我们就可以重启 Zookeeper 服务端,打开 JConsole 界面,输入 Zookeeper 地址和开放的 JMX 端口,然后就能监控 Zookeeper 的 Java 进程了。除了使用 JConsole 来监控 Zookeeper 进程的运行状态之外,我们还可以使用 Zookeeper 提供的四字监控命令来查看Zookeeper 进程的运行状态,那么接下来我们就来学习 Zookeeper 的四字监控命令。
- 3.1 Django 中 Cookie 操作相关源码 从前面的操作 Cookie 讲解中,我们只用到了和增和查两部分的方法,分别对应 HttpResponse 和 HttpRequest 两个类。接下来,我们去对应的源码中查找所涉及的和 Cookie 相关的代码。request.COOKIES['xxx']request.COOKIES.get('xxx', None)# 源码位置:django/core/handlers/wsgi.pyclass WSGIRequest(HttpRequest): # ... @cached_property def COOKIES(self): raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '') return parse_cookie(raw_cookie) # ...# 源码位置:django/http/cookie.pyfrom http import cookies# For backwards compatibility in Django 2.1.SimpleCookie = cookies.SimpleCookie# Add support for the SameSite attribute (obsolete when PY37 is unsupported).cookies.Morsel._reserved.setdefault('samesite', 'SameSite')def parse_cookie(cookie): """ Return a dictionary parsed from a `Cookie:` header string. """ cookiedict = {} for chunk in cookie.split(';'): if '=' in chunk: key, val = chunk.split('=', 1) else: # Assume an empty name per # https://bugzilla.mozilla.org/show_bug.cgi?id=169091 key, val = '', chunk key, val = key.strip(), val.strip() if key or val: # unquote using Python's algorithm. cookiedict[key] = cookies._unquote(val) return cookiedict上面的代码并不复杂,在 WSGIRequest 类中的 COOKIES 属性是先从客户端请求中取出 Cookie 信息,调用 get_str_from_wsgi() 方法是从 WSGI 中拿到对应的 Cookie 字符串。接下来用 parse_cookie() 方法将原始 Cookie 字符串中的 key=value 解析出来做成字典形式并返回。这就是为什么我们能像操作字典一样操作 request.COOKIES 的原因。下面的方法是实验1中调用的 get_signed_cookie() 的源码,也不复杂,同样是从self.COOKIES 中取出对应 key 的 value 值,然后使用对应的 salt 解密即可。# 源码位置:django/http/request.py class HttpRequest: # ... def get_signed_cookie(self, key, default=RAISE_ERROR, salt='', max_age=None): """ Attempt to return a signed cookie. If the signature fails or the cookie has expired, raise an exception, unless the `default` argument is provided, in which case return that value. """ try: cookie_value = self.COOKIES[key] except KeyError: if default is not RAISE_ERROR: return default else: raise try: value = signing.get_cookie_signer(salt=key + salt).unsign( cookie_value, max_age=max_age) except signing.BadSignature: if default is not RAISE_ERROR: return default else: raise return value # ...接下来是涉及到创建 Cookie 的方法,我们需要查找 HttpResponse 类或者相关的父类:# 源码位置:django/http/response.pyclass HttpResponseBase: # ... def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None): """ Set a cookie. ``expires`` can be: - a string in the correct format, - a naive ``datetime.datetime`` object in UTC, - an aware ``datetime.datetime`` object in any time zone. If it is a ``datetime.datetime`` object then calculate ``max_age``. """ self.cookies[key] = value if expires is not None: if isinstance(expires, datetime.datetime): if timezone.is_aware(expires): expires = timezone.make_naive(expires, timezone.utc) delta = expires - expires.utcnow() # Add one second so the date matches exactly (a fraction of # time gets lost between converting to a timedelta and # then the date string). delta = delta + datetime.timedelta(seconds=1) # Just set max_age - the max_age logic will set expires. expires = None max_age = max(0, delta.days * 86400 + delta.seconds) else: self.cookies[key]['expires'] = expires else: self.cookies[key]['expires'] = '' if max_age is not None: self.cookies[key]['max-age'] = max_age # IE requires expires, so set it if hasn't been already. if not expires: self.cookies[key]['expires'] = http_date(time.time() + max_age) if path is not None: self.cookies[key]['path'] = path if domain is not None: self.cookies[key]['domain'] = domain if secure: self.cookies[key]['secure'] = True if httponly: self.cookies[key]['httponly'] = True if samesite: if samesite.lower() not in ('lax', 'strict'): raise ValueError('samesite must be "lax" or "strict".') self.cookies[key]['samesite'] = samesite def set_signed_cookie(self, key, value, salt='', **kwargs): value = signing.get_cookie_signer(salt=key + salt).sign(value) return self.set_cookie(key, value, **kwargs) def delete_cookie(self, key, path='/', domain=None): # Most browsers ignore the Set-Cookie header if the cookie name starts # with __Host- or __Secure- and the cookie doesn't use the secure flag. secure = key.startswith(('__Secure-', '__Host-')) self.set_cookie( key, max_age=0, path=path, domain=domain, secure=secure, expires='Thu, 01 Jan 1970 00:00:00 GMT', ) # ...从上面的代码可以看到,最核心的方法是 set_cookie(),而删除 cookie 和 设置加盐的 cookie 方法最后都是调用 set_cookie() 这个方法。而这个方法也比较简单,就是将对应的传递过来的参数值加到 self.cookies 这个字典中。最后我们思考下,难道就这样就完了吗?是不是还需要有一步是需要将 self.cookies 中的所有 key-value 值组成字符串,放到头部中,然后才返回给前端?事实上,肯定是有这一步的,代码如下。在用 “#” 号包围起来的那一段代码正是将 self.cookies 中的所有 key-value 值组成字符串形式,然后放到头部的 “Set-Cookie” 中,正是有了这一步的动作,我们前面设置的 self.cookie 内部的 key-value 值才能真正生效。# 源码位置:django/core/handlers/wsgi.pyclass WSGIHandler(base.BaseHandler): request_class = WSGIRequest def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.load_middleware() def __call__(self, environ, start_response): set_script_prefix(get_script_name(environ)) signals.request_started.send(sender=self.__class__, environ=environ) request = self.request_class(environ) response = self.get_response(request) response._handler_class = self.__class__ status = '%d %s' % (response.status_code, response.reason_phrase) ############################################################################## response_headers = [ *response.items(), *(('Set-Cookie', c.output(header='')) for c in response.cookies.values()), ] ############################################################################# start_response(status, response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) return response
unless相关搜索
-
ubuntu安装
ubuntu安装教程
ubuntu官网
ucenter
udp通信
ui层
uml
uml类图
uml建模
uml教程
uml图
underscore
uni app
unicode
uniform
union
union用法
uniq
uniqueconstraint
uniqueid