粗略介绍下python中函数的根基语法

python 函数

 
 对于.NET的分布式应用开发,可以供大家采纳的技巧和框架相比多,例如webservice,.net
remoting,MSMQ,WCF等等技术。对于那多少个技能很几人都不会陌生,即时没有浓厚的了解,可是毫无疑问听说过,每种技术都各有优势和适用范围,没有相对的上下,唯有绝对的恰当程度。不过可惜了,明天我们讲解的要旨不是这两种技术,明日关键讲解的是ASP.NET
WebAPI。

定义

函数是指将一组语句的集结通过一个名字(函数名)封装起来,要想举行这么些函数,只需调用其函数名即可。

   对于ASP.NET
WebAPI的优势和特色,在这边就不讲了,需要动用的自然就会选拔,也不需要自我浪费篇幅去讲授这个,这篇博文首要教师ASP.NET
WebAPI中的HTTP音信的布局和拍卖信息的骨干目的。

特性

  1. 减去代码重复
  2. 使程序变得可扩展
  3. 使程序变得容易维护

一.WebAPI的HTTP概述:

 
 有关HTTP协议的相干内容在这边就不做牵线,在笔者前边的博文中早就做过介绍,现在提供一下地点,因为过多的废话就是浪费时间,我就姑且看这篇博文的读者已经对HTTP协议和WebAPI都有着领悟。博文地址:

http://www.cnblogs.com/pengze0902/p/5976388.html

http://www.cnblogs.com/pengze0902/p/6224792.html

http://www.cnblogs.com/pengze0902/p/6230105.html

函数的创制

python中创设函数,需要动用__def__重中之重字,前面写函数的名字,然后是形参列表,大体如下:

def 函数名(形参列表):
    函数体......
    return 返回值

里头形参列表和 return再次回到值并不是必须的。

   1.在.NET4.5事先的版本中,处理HTTP的着力目的:

     
(1).在客户端:System.Net.HttpWebRequest用于起先化HTTP请求,处理有关的响应; System.Net.HttpWebResponse处理HTTP响应头和数量读取的搜寻。

     
(2).在服务器端:System.Web.HttpContext,System.Web.HttpRequest,System.Web.HttpResponse类用在ASP.NET上下文中,代表单个请求和响应。System.Net.HttpListenerContext类,提供对HTTP请求和响应对象的拜会。

函数的采用

想要调用函数程序,需要以函数名加括号的花样开展调用,而括号内可以流传参数,而括号内的参数大家称为__实参列表__,传入的实参会通过形参传递进函数,在函数内部就足以应用了。如下:

def add(x,y):
    return x + y

# 调用函数
add(10,20)

急需注意的是,python中的实参列表每一个参数在此以前用逗号分割,而向add()括号内的10,20这么的参数我们誉为地方参数(positional
argument)。

那么需要专注的是,在python中,函数的实参的个数必须和形参的个数一样,实参个数多于形参或者少于形参都会报错。

   2.在.NET4.5本子中,处理HTTP的主导目标:

     
(1).在客户端和劳务器端使用同一的类。(HttpRequestMessage和HttpResponseMessage对象中不带有上下文信息,所以可以在服务器和客户端共用。)

     
(2).由于在.NET4.5中引入了TAP(异步任务模型),所以在新的HTTP模型中,处理HTTP请求的方法可以行使async和awit实现异步编程。(可以大概神速的落实异步编程)

   
我们对此新旧的HTTP编程模型时,会很容易的觉察在新本子的HTTP模型中,无论是编程的难度和代码编写的精简度,已经实施的效用都是很高的。在对于Web项目标支付中,我们对HTTP知识的摸底是必需的,对于ASP.NET的HTTP处理的原理在此间就不做具体的牵线,网上也有相比多的篇章可供阅读和精通。

   
对于ASP.NET的HTTP处理方式的问询,是自身在开发微信公众平台时更加学习的,微信公众平台提供了对外访问的接口,我们的程序和服务器对微信服务器的接口举行呼吁访问,微信服务器获取HTTP请求后,重返处理结果,本地服务器获取重临结果。这样一个请求-响应格局,组成一个会话。对于微信公众平台的支出对于众多刚学习.NET的人的话多少高大(当然这是对峙而言),即时开发过很频繁这些类型的主次的人(调用第三方接口的支付)也不必然可以很清楚的了解这么些里面的法则,笔者觉得对于如此的第三方平台的开发,其关键的着力部分就是对于HTTP协议的处理,建立请求、获取响应信息和分析消息这三大步子,再次回到的音讯内容一般为json或者xml,获取响应音讯后,重即使对信息内容的反系列化,得到信息的实体信息,进而在先后中更是处理。

   
在WeAPI中消息的发出和剖析,以及新闻的格式都是可以动态的成立和商谈,下面大家尤其的刺探实现这一过程的骨干目标。

函数的参数

形参也足以叫做形参变量,只有在被调用时才分配内存单元,在调用截至时,即自由所分配的内存单元。所以形参只可以在函数内部生效。函数调用截止再次回到主调用函数后则不能再使用该形参变量。

实参可以是常量、变量、表明式、函数等,无论实参是何系列型的量,在进展函数调用时,它们都不可以不有确定的值,以便把那么些值传送给形参。因而应优先用赋值,输入等模式使参数得到确定值

图片 1

二.WebAPI的HTTP音信分析:

     
HTTP协议的劳作办法是在客户端和服务器之间互换请求和响应新闻,那么这也就可以表达HTTP的着力就是音信,对于“音信”的问询,我们即便通晓消息分为“信息头部”和“音信内容”,我们接下去的对新HTTP编程模型的牵线的主体就是“新闻头部”和“音信内容”。

     
在命名空间System.Net.Http中,具有两个着力目的:HttpRequestMessage和HttpResponseMessage。两个目的的布局如下图:

图片 2

     
以上重大助教了HttpRequestMessage对象和HttpResponseMessage对象涵盖的关键内容,请求和响应信息都可以蕴涵一个可选的音信正文,两中信息类型以及音讯内容,都足以运用响应的标头。接下来具体精晓一些音信的构造。

默认参数

首先,先来看上面的代码:

def stu_register(name,age,country,course):
    print('------注册学生信息--------')
    print('学员姓名:',name)
    print('学员年龄:',age)
    print('学员国籍:',country)
    print('学员选择课程:',course)

stu_register('小明',19,'中国','web前端')
stu_register('小红',20,'中国','linux')
stu_register('李白',25,'中国','python')

在上头的实例中,每一个学童登记的国籍都是礼仪之邦,而在网上的一对网站中,假使不去手动设置,都默认为中国,这就是通过默认参数实现的。

一般来说,把country变成默认参数,

def stu_register(name,age,course,country='中国')

这就是说此时再登记学员的时候假设国籍是神州就可以不需要进行国籍的传参,而是采用默认的参数。

    1.HttpRequestMessage目的解析:

         (1).HttpRequestMessage紧要性能和章程概述:

名称 说明
Version 获取或设置 HTTP 消息版本
Content 获取或设置 HTTP 消息的内容
Method 获取或设置 HTTP 请求信息使用的 HTTP 方法
RequestUri 获取或设置 HTTP 请求的 Uri
Headers 获取 HTTP 请求标头的集合
Properties 获取 HTTP 请求的属性集
ToString 返回表示当前对象的字符串

        该对象首要用来表示 HTTP
请求信息。对于该目的的这多少个属性和章程,大部分相应都不会陌生,因为一个HTTP信息中一言九鼎含有头部、音信内容等等,在这里根本介绍一个特性Properties,该属性并不属于其他正规的HTTP消息,当音讯传输时,不会保留该属性。

         (2).Properties属性解析:

[__DynamicallyInvokable]
public IDictionary<string, object> Properties
{
    [__DynamicallyInvokable]
    get
    {
        if (this.properties == null)
        {
            this.properties = new Dictionary<string, object>();
        }
        return this.properties;
    }
}

   
有上述的代码可以很显明的看来该属性唯有一个只读属性,并回到一个IDictionary<string,
object>。当消息在服务器或者客户端本地开展拍卖时,该属性用于保存附加的信息消息。该属性只是一个通用的器皿,保存本地信息属性。(与接受音讯的连天相关的客户端认证;将消息与安排路由举行匹配,得到的路由数据)

首要参数

好端端情状下,给函数传参数要按梯次,不想按顺序就可以用关键参数,只需点名参数名即可,但切记一个要求就是,关键参数必须放在地方参数之后。

# 使用关键字参数
stu_register(name='小明',country='中国',age=19,course='linux')
'''关键字参数必须放在位置参数之后'''
stu_register('小红',country='中国',age=19,course='linux')

   2.HttpResponseMessage对象解析:

        (1).HttpRequestMessage紧要性能和办法概述:

名称 说明
EnsureSuccessStatusCode 如果 HTTP 响应的 IsSuccessStatusCode 属性为  false, 将引发异常
StatusCode 获取或设置 HTTP 响应的状态代码
ReasonPhrase 获取或设置服务器与状态代码通常一起发送的原因短语
RequestMessage 获取或设置导致此响应消息的请求消息
IsSuccessStatusCode 获取一个值,该值指示 HTTP 响应是否成功

     
对于该对象的部分特性没有列举,因为在HttpRequestMessage对象已经介绍,如:Version、Content、Headers等,该目标重要用来表示
HTTP 响应信息。在这里紧要介绍StatusCode属性。

       (2).StatusCode属性:

[__DynamicallyInvokable]
public HttpStatusCode StatusCode
{
    [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    get
    {
        return this.statusCode;
    }
    [__DynamicallyInvokable]
    set
    {
        if ((value < ((HttpStatusCode) 0)) || (value > ((HttpStatusCode) 0x3e7)))
        {
            throw new ArgumentOutOfRangeException("value");
        }
        this.CheckDisposed();
        this.statusCode = value;
    }
}

   
 StatusCode属性为枚举属性,该属性可读可写,对于状态码这多少个概念,很六人都是相比较精晓的,在HTTP协议中,状态码紧倘诺象征在音讯的央浼在服务器中拍卖的结果,状态有2XX,3XX,4XX,5XX等等,具体表示的含义就不再描述。

非固定参数

一经你的函数中并不是很确定用户会传来多少个参数,那么就可以运用非固定参数。

'''非固定参数'''
def test01(x,y,*args):
    print(x,y)
    print(args)

test01('李白','艳艳',12,3,4)

出口结果为:

李白 艳艳
(12, 3, 4)

内需专注的是,当使用了*args的时候,会发觉传入的参数全体被放在了一个元组中。那么一旦想要操作的话只需遵照元组的操作方法操作即可。

非固定参数除了可以变换成元组以外,仍是可以将盛传的多寡转换成字典,需要利用**kwargs,代码如下:

def stu_register(name,age,*args,**kwargs): # *kwargs 会把多传入的参数变成一个dict形式
    print(name,age,args,kwargs)

stu_register("Alex",22)
#输出
#Alex 22 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空

stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong")
#输出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}

     3.HTTP模型消息标头解析:

         
在HTTP中,请求和响应消息,以及音讯内容本身,都可以应用称为标头的附加字段,包含更多的信息。

       (1).标头分类:

标头名称 描述 HTTP模型标头容器类
User-Agent 为请求提供扩展信息,描述产生这个请求的应用程序 HttpRequestHeaders
Server 为响应提供关于源服务器软件的扩展信息 HttpResponseHeaders
Content-Type 定义请求或响应有效载荷正文中,资源表示使用的媒体类型 HttpContentHeaders

       (2).HttpHeaders抽象类分析:

名称 描述
Add 添加指定的标头及其值到 HttpHeaders 集合中。
TryAddWithoutValidation 返回一个值,该值指示指定标头及其值是否已添加到HttpHeaders 集合,而未验证所提供的信息。
Clear 从 HttpHeaders 集合中移除所有标头。
Remove 从HttpHeaders集合中移除指定的标头。
GetValues 返回存储在HttpHeaders 集合中所有指定标头的标头值。
Contains 如果指定标头存在于 HttpHeaders 集合则返回。
ToString 返回表示当前 HttpHeaders对象的字符串。

     
 HttpHeaders是一个抽象类,HttpRequestHeaders、HttpResponseHeaders、HttpContentHeaders六个类继承了此类。接下来大家来打探一下Add()方法:

[__DynamicallyInvokable]
public void Add(string name, string value)
{
    HeaderStoreItemInfo info;
    bool flag;
    this.CheckHeaderName(name);
    this.PrepareHeaderInfoForAdd(name, out info, out flag);
    this.ParseAndAddValue(name, info, value);
    if (flag && (info.ParsedValue != null))
    {
        this.AddHeaderToStore(name, info);
    }
}

     
 Add()方法具有五个重载版本,该措施能够向容器添加标头,假如要丰盛的标头有标准名,在增长此前标头值会举行表达。Add方法还会注解标头是否足以有四个值。

一部分变量和全局变量

在python中,函数外部讲明的变量大家称为全局变量,在函数内部宣称的变量是有些变量。

全局变量可以在变量讲明之后的此外岗位采用,而一些变量只能在函数内部使用。

'''全局变量和局部变量'''
name = '李白' # 函数外部声明 ,称之为全局变量

def test():
    age = 20 # 函数内部声明,称之为局部变量
    print(age) # 局部变量只能够在函数内部使用
    print(name) # 全局变量可以在函数内部使用
test()
# print(age) 在函数外部没有办法使用局部变量

__tip:函数内部宣称全局变量__

假如想要在函数内部宣称全局变量,需要动用global关键字

def test():
    global test
    test = '李白斗酒诗百篇'
test()
print(test) # 李白斗酒诗百篇

透过global关键字就可以在函数内部创建全局变量,可是那种写法是不推荐使用的,有可能造成变量污染。

还有一些亟待专注,看下面的代码:

name = '艳艳'

def test():
    # 在函数中更改全局变量name的值
    name = 'hello,world'
    print(name) # hello,world
test()
print(name) # 艳艳

上述代码中,在函数中对全局变量进行了转移,并且打印更改之后的变量,那么打印的结果是更改的结果,不过在函数的外围再度打印在函数中改变的全局变量,发现结果并不曾被更改,因为在函数中改变全局变量,那么更改过后的值功能域仅停留在函数当中。

那么怎么样在函数中对全局变量更改并且在函数外部调用结果为改观之后的值吗?同样可以采取global关键字来兑现。

name = '艳艳'

def test():
    global name
    # 在函数中更改全局变量name的值
    name = 'hello,world'
    print(name) # hello,world
test()
print(name) # hello,world

   4.HTTP音信内容分析:

     
在.NET4.5版本的HTTP模型中,HTTP信息的正文由抽象基类HttpContent表示,HttpResponseMessage和HttpRequestMessage对象都蕴含一个HttpContent类型的Content属性。

     (1).HttpContent重要性能和方法:

名称 描述
ReadAsByteArrayAsync 以异步操作将 HTTP 内容写入字节数组。
SerializeToStreamAsync 以异步操作将 HTTP 内容序列化到流。
CopyToAsync 以异步操作将 HTTP 内容写入流。
LoadIntoBufferAsync 以异步操作将 HTTP 内容序列化到内存缓冲区。
CreateContentReadStreamAsync 以异步操作将 HTTP 内容写入内存流。
TryComputeLength 确定 HTTP 内容是否具备有效的字节长度。
Headers 根据 RFC 2616 中的定义,获取内容标头。

     (2).CopyToAsync()方法分析:

[__DynamicallyInvokable]
public Task CopyToAsync(Stream stream, TransportContext context)
{
    Action<Task> continuation = null;
    this.CheckDisposed();
    if (stream == null)
    {
        throw new ArgumentNullException("stream");
    }
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    try
    {
        Task task = null;
        if (this.IsBuffered)
        {
            task = Task.Factory.FromAsync<byte[], int, int>(new Func<byte[], int, int, 
            AsyncCallback, object, IAsyncResult>(stream.BeginWrite), new Action<IAsyncResult>(stream.EndWrite), 
       this.bufferedContent.GetBuffer(), 0, (int) this.bufferedContent.Length, null);
        }
        else
        {
            task = this.SerializeToStreamAsync(stream, context);
            this.CheckTaskNotNull(task);
        }
        if (continuation == null)
        {
            continuation = delegate (Task copyTask) {
                if (copyTask.IsFaulted)
                {
                    tcs.TrySetException(GetStreamCopyException(copyTask.Exception.GetBaseException()));
                }
                else if (copyTask.IsCanceled)
                {
                    tcs.TrySetCanceled();
                }
                else
                {
                    tcs.TrySetResult(null);
                }
            };
        }
        task.ContinueWithStandard(continuation);
    }
    catch (IOException exception)
    {
        tcs.TrySetException(GetStreamCopyException(exception));
    }
    catch (ObjectDisposedException exception2)
    {
        tcs.TrySetException(GetStreamCopyException(exception2));
    }
    return tcs.Task;
}

   
在选用音信内容时,需要采纳HtppContent的法门或者扩张方法。在HttpContent中应用CopyToAsync()方法以推送情势访问原本的信息内容,由艺术代码可以看到,该模式接受五个参数,一个是流对象,一个是关于传输的信息(例如,通道绑定),此参数可以为
null。该措施可以把信息内容写入到这些流中。

    在该方法的实现代码中
成立了一个TaskCompletionSource<object>的泛型对象,该目的表示未绑定到委托的 Task<TResult> 的创立者方,并因此 Task 属性提供对使用者方的走访。SerializeToStreamAsync方法将盛传的流对象系列化,该办法为异步方法。

   
大家需要注意的几点,紧要为委托的创始和行使,在C#中,尽量使用有.NET提供的委托类,不要自己去创建。还有少数就是在程序中对充足的处理情势,至极的抓获具有层次性,并且调用了自定义的一个十分处理方法TrySetException。

    (2).ReadAsStreamAsync()方法分析:

     
在收获原始音信内容时,除了调用下边介绍的措施外,还足以调用ReadAsStreamAsync()方法以拉取的艺术访问原本的音信内容。

     
在HttpContent中带有有此外多少个类似的办法,ReadAsStringAsync()和ReadAsByteArrayAsync()异步的提供音信内容的缓冲副本,ReadAsByteArrayAsync()重返原始的字节内容,ReadAsStringAsync()将内容解码为字符串重返。

返回值

要想取得函数的实施结果,就可以用return语句把结果回到

注意:

函数在实践进程中只要曰镪return语句,就会结束执行并赶回结果,so
也得以清楚为 return 语句代表着函数的完结
万一未在函数中指定return,这这么些函数的重回值为None 。

三.DotNet中新旧HTTP模型解析:

递归函数

在函数内部,可以调用其他函数。假设一个函数在其中调用自己本身,那一个函数就是递归函数。

'''创建一个递归,将传入的参数不断的除以2,到0为止'''
def calc(n):
    print(n)
    if int(n/2) > 0 :
        return calc( int(n/2) )

calc(10)

出口结果为:

10
5
2
1

递归特性:

  1. 务必有一个众所周知的利落条件

  2. 每便进入更深一层递归时,问题规模相比较上次递归都应拥有压缩

  3. 递归效能不高,递归层次过多会招致栈溢出(在电脑中,函数调用是透过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数重回,栈就会减一层栈帧。由于栈的尺寸不是最最的,所以,递归调用的次数过多,会促成栈溢出)

堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html

   1..NET4.5往日版本创制HTTP POST请求实例:

        public static string HttpPost(string postUrl, string postData)
        {
            if (string.IsNullOrEmpty(postUrl))
                throw new ArgumentNullException(postUrl);
            if (string.IsNullOrEmpty(postData))
                throw new ArgumentNullException(postData);
            var request = WebRequest.Create(postUrl) as HttpWebRequest;
            if (request == null)
                throw new ArgumentNullException("postUrl");
            try
            {
                var cookieContainer = new CookieContainer();
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                var data = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = data.Length;
                var outstream = request.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Close();
                //发送请求并获取相应回应数据,获取对应HTTP请求的响应
                var response = request.GetResponse() as HttpWebResponse;
                if (response != null)
                {
                    var instream = response.GetResponseStream();
                    var content = string.Empty;
                    if (instream == null)
                    {
                        return content;
                    }
                    using (var sr = new StreamReader(instream, Encoding.UTF8))
                    {
                        content = sr.ReadToEnd();
                    }
                    return content;
                }
            }
            catch (ArgumentException arex)
            {
                throw arex;
            }
            catch (IOException ioex)
            {
                throw ioex;
            }
            return null;
        }

   2..NET4.5版本创设HTTP POST请求实例:

async static void getResponse(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                using (HttpResponseMessage response = await client.GetAsync(url))
                {
                    using (HttpContent content = response.Content)
                    {
                        string myContent = await content.ReadAsStringAsync();
                    }
                }
            }
        }
        async static void postResponse(string url)
        {
            while (true)
            {
                IEnumerable<KeyValuePair<string, string>> queries = new List<KeyValuePair<string, string>>()
            {
                new KeyValuePair<string, string> ("test","test")
            };
                HttpContent q = new FormUrlEncodedContent(queries);
                using (HttpClient client = new HttpClient())
                {
                    using (HttpResponseMessage response = await client.PostAsync(url, q))
                    {
                        using (HttpContent content = response.Content)
                        {
                            string myContent = await content.ReadAsStringAsync();

                            Console.WriteLine(myContent);
                        }
                    }
                }
            }
        }

四.总结:

 
 以上紧要讲解了.NET4.5事先和今后版本对HTTP编程格局的一些情节, 两者的要紧区别在于.NET4.5版本之前的HTTP编程模型会区分客户端和服务器,两者采纳的目的存在不同,实现的原理上即使存在一定的相似性,不过使用的类却不比。.NET4.5事后的本子中,对象的行使没有客户端和服务器之分,两者可以共用。