python-函数篇

图片 1怎么时候我不应该运用泛型?对泛型笔者应该运用什么命名规范?小编应当在泛型接口上面添加约束吗?
图片 2哪些惩处(Dispose)泛型接口?能够对一般项目参数进行类型转换吗?
图片 3对泛型类怎么样同步多线程访问?怎样系列化泛型类?
图片 4
图片 5何以时候作者不该运用泛型?
图片 6
图片 7        不应用泛型的重点原因正是跨目标(cross-targeting)——假若您要在.NET 1.1和.NET 2.0下编写翻译相同的代码,那么由于只有.NET 2.0帮忙泛型,你就不可见利用泛型。
图片 8
图片 9
图片 10对泛型笔者应该使用什么命名规范?
图片 11
图片 12        作者提议利用三个单独的大写字母来表示一般项目参数。假若你对项目参数没有此外的跟上下文有关的信息(additional contextual information),你应当使用字母T:
图片 13
图片 14public class MyClass<T>
图片 15图片 16图片 17{图片 18}
图片 19      
图片 20 在具备别的场合下,微软标准的对泛型的的命名规范引导是:
图片 21
图片 22相似项目参数要有描述性的名字,除非一个单身的假名已经表示得很掌握,再追加描述性的名字也并未多大用处。
图片 23
图片 24public interface ISessionChannel<TSession> 
图片 25图片 26图片 27{图片 28}
图片 29public delegate TOutput Converter<TInput,TOutput>(TInput from);
图片 30能够考虑在形似品种参数的名字中意味出添加给该一般项目参数的牢笼。例如,3个被封锁到ISession接口的参数可以起名为TSession。
图片 31笔者应当在泛型接口上边添加约束吗?
图片 32
图片 33        接口能够为其行使的范型类型丰硕约束,例如:  
图片 34
图片 35public interface ILinkedList<T> where T : IComparable<T>
图片 36图片 37图片 38{图片 39}
图片 40  然则,你应当小心,在接口层面上定义约束还含有有其余一层意思。为了强调接口与完成分离的思维,接口不应该包含别的一点贯彻的细节。尽管有众多措施能够用来促成范型接口,可是利用一定的连串参数毕竟是一种达成的底细。约束平日状态下会特别耦合(couple)接口和特定的贯彻。
图片 41
图片 42        更好的方法是,为贯彻范型接口的类添加约束,保持接口本身没有约束:
图片 43
图片 44public class LinkedList<T> : ILinkedList<T> where T : IComparable<T>
图片 45图片 46图片 47{
图片 48   //Rest of the implementation  
图片 49}
图片 50什么样惩处(Dispose)泛型接口?
图片 51
图片 52      在C#和Visual Basic中,若是您把3个一般品种参数的靶子放在using语句中,编写翻译器不能清楚客户端(client)内定的实际上类型是不是协助IDisposable接口。由此编译器不容许在using语句中选择相似品种参数的实例。
图片 53
图片 54public class MyClass<T> 
图片 55图片 56图片 57{
图片 58   public void SomeMethod(T t)
图片 59图片 60   图片 61{
图片 62      using(t)//Does not compile 
图片 63图片 64      图片 65{图片 66}
图片 67   }
图片 68}
图片 69理所当然,你能够强制约束类型参数帮助IDisposable接口:
图片 70
图片 71public class MyClass<T> where T : IDisposable 
图片 72图片 73图片 74{
图片 75   public void SomeMethod(T t)
图片 76图片 77   图片 78{
图片 79      using(t)
图片 80图片 81      图片 82{图片 83}
图片 84   }
图片 85}
图片 86     然则您不应该这么做。这样做的难点在于你无法应用接口作为项目参数了,固然那些接口的根底项目(underlying type)帮助IDisposable也相当:
图片 87
图片 88public interface IMyInterface
图片 89图片 90图片 91{}
图片 92public class MyOtherClass : IMyInterface,IDisposable 
图片 93图片 94图片 95{图片 96}
图片 97public class MyClass<T> where T : IDisposable 
图片 98图片 99图片 100{
图片 101   public void SomeMethod(T t)
图片 102图片 103   图片 104{
图片 105      using(t)
图片 106图片 107      图片 108{图片 109}
图片 110   }
图片 111}
图片 112MyOtherClass myOtherClass = new MyOtherClass();
图片 113MyClass<IMyInterface> obj = new MyClass<IMyInterface>();//Does not compile
图片 114obj.SomeMethod(myOtherClass); 
图片 115  作为代表,作者提议你在using语句里对一般品种参数使用C#中的as操作符恐怕Visual Basic中的TryCast操作符来允许接口作为一般项目参数使用:
图片 116
图片 117
图片 118public class MyClass<T> 
图片 119图片 120图片 121{
图片 122   public void SomeMethod(T t)
图片 123图片 124   图片 125{
图片 126      using(t as IDisposable)
图片 127图片 128      图片 129{图片 130}
图片 131   }
图片 132}
图片 133能够对一般品种参数举办类型转换吗?
图片 134
图片 135        对于隐式转换,编写翻译器只同意将一般项目参数转换为object类型,大概其约束里钦赐的不胜类型:
图片 136
图片 137interface ISomeInterface
图片 138图片 139图片 140{图片 141}
图片 142class BaseClass
图片 143图片 144图片 145{图片 146}
图片 147class MyClass<T> where T : BaseClass,ISomeInterface
图片 148图片 149图片 150{
图片 151   void SomeMethod(T t)
图片 152图片 153   图片 154{
图片 155      ISomeInterface obj1 = t;
图片 156      BaseClass      obj2 = t;
图片 157      object         obj3 = t;
图片 158   }
图片 159}
图片 160那种隐式转换当然是连串安全的,因为无效的转移在编写翻译时就会被发觉。
图片 161
图片 162        对于展现转换,编写翻译器允许将一般品种参数转换来别的接口,不过不能够更换为类:
图片 163
图片 164interface ISomeInterface
图片 165图片 166图片 167{图片 168}
图片 169class SomeClass
图片 170图片 171图片 172{图片 173}
图片 174class MyClass<T> 
图片 175图片 176图片 177{
图片 178   void SomeMethod(T t)
图片 179图片 180   图片 181{
图片 182      ISomeInterface obj1 = (ISomeInterface)t;//Compiles
图片 183      SomeClass      obj2 = (SomeClass)t;     //Does not compile
图片 184   }
图片 185}
图片 186 但是,你能够由此使用二个一时半刻的object类型变量来强制将一般品种参数转到到别的其余项目:
图片 187
图片 188class MyOtherClass
图片 189图片 190图片 191{图片 192}
图片 193
图片 194class MyClass<T> 
图片 195图片 196图片 197{
图片 198  
图片 199   void SomeMethod(T t)
图片 200   
图片 201图片 202   图片 203{
图片 204      object temp = t;
图片 205      MyOtherClass obj = (MyOtherClass)temp;
图片 206   
图片 207   }
图片 208}
图片 209一定,这样的来得转换是很凶险的,因为一旦实际行使的替代一般品种参数的品种不是从你要更换来的品种那里继承的话,就恐怕在运转时抛出尤其。
图片 210
图片 211        为了幸免那种转移时有格外的高危害,二个更好的点子是选拔is或许as操作符。尽管相似品种参数是(is)要查询的花色,is 操作符会再次回到true,而as操作符会在多个类型包容的时候实施转换,不然将再次回到null。
图片 212
图片 213public class MyClass<T> 
图片 214图片 215图片 216{
图片 217   public void SomeMethod(T t)
图片 218图片 219   图片 220{
图片 221      if(t is int)
图片 222图片 223      图片 224{图片 225
图片 226
图片 227      if(t is LinkedList<int,string>)
图片 228图片 229      图片 230{图片 231}
图片 232
图片 233      string str = t as string;
图片 234      if(str != null)
图片 235图片 236      图片 237{图片 238}
图片 239
图片 240      LinkedList<int,string> list = t as LinkedList<int,string>;
图片 241      if(list != null)
图片 242图片 243      图片 244{图片 245}
图片 246   }
图片 247}
图片 248
图片 249
图片 250
图片 251对泛型类怎么样同步八线程访问?
图片 252
图片 253        平日来说,你不应有在一般项目参数上行使Monitor。那是因为Monitor只能用来引用类型。当你利用范型的时候,编写翻译器不可能预先判断你将会提供1个引用类型恐怕值类型的类型参数。在C#中,编写翻译器会同意你使用lock语句,不过一旦你提供了2个值类型作为项目参数,lock语句在运转时将不起成效。在Visual Basic中,编写翻译器借使不能够分明一般品种参数是3个引用类型,它将不容许在形似项目参数方面运用SyncLock。
图片 254
图片 255        在C#和Visual Basic中,唯一你能够安全地将一般品种参数锁住的时候,是您将一般项目参数限制为引用类型,要么添加约束使其为引用类型,要么从一个基类中三番五次:
图片 256
图片 257public class MyClass<T> where T : class
图片 258图片 259图片 260{..}
图片 261
图片 262public class SomeClass
图片 263图片 264图片 265{图片 266}
图片 267public class MyClass<T> where T : SomeClass
图片 268图片 269图片 270{图片 271}
图片 272     可是,平日对于联合来说,最棒制止某个地锁住单独的分子变量,因为这会追加死锁的或者性。
图片 273
图片 274怎么样类别化泛型类?
图片 275
图片 276        包蕴了貌似品种参数作为成员的范型类是能够被标记为种类化的:
图片 277
图片 278[Serializable]
图片 279public class MySerializableClass<T>
图片 280图片 281图片 282{
图片 283   T m_T;
图片 284}
图片 285  不过,在那种状态下,唯有钦赐的类型参数能够被类别化时,范型类才得以被类别化。看下边包车型地铁代码:
图片 286
图片 287
图片 288public class SomeClass
图片 289图片 290图片 291{}
图片 292MySerializableClass<SomeClass> obj;
图片 293  obj不能够被系列化,因为项目参数SomeClass不得以被种类化。由此,My塞里alizableClass<T>恐怕能够,也说不定不能被种类化,取决于使用的形似品种参数。那样或者引致在运维时丢失数据或然系统崩溃,因为客户应用程序恐怕不可见保险对象的情况。
图片 294
图片 295        方今,.NET没有提供将一般项目参数约束为可种类化的机制。化解办法是在运营时在采纳这一个项目在此之前单独举办检讨,并且在任何损害爆发从前及时刹车使用。你能够把那么些运营时的印证放在静态构造器里面:
图片 296
图片 297[Serializable]
图片 298class MySerializableClass<T>
图片 299图片 300图片 301{
图片 302   T m_T;
图片 303
图片 304   static MySerializableClass()   
图片 305图片 306   图片 307{
图片 308      ConstrainType(typeof(T));
图片 309   }
图片 310   static void ConstrainType(Type type)
图片 311图片 312   图片 313{
图片 314      bool serializable = type.IsSerializable;
图片 315      if(serializable == false)
图片 316图片 317      图片 318{
图片 319         string message = “The type ” + type + ” is not serializable”;
图片 320         throw new InvalidOperationException(message);
图片 321      }
图片 322   }
图片 323}
图片 324 静态构造器对每叁个运用程序域的每二个品类只进行三遍,而且是在档次第1次被呼吁实例化以前。固然你有部分通过编制程序的情势来在运营时实行判定和举行检查,不过那种在静态构造器里面实践约束验证的技巧,对别的不可能在编写翻译时展开自笔者批评的约束都适用。
图片 325
图片 326

python函数基础

一.函数

1.函数简介

函数是团队好的,可重复使用的,用来兑现单一,或相关联功用的代码段。

函数能增进运用的模块性,和代码的再度利用率。你曾经知道Python提供了好多内建函数,比如print()。但你也足以团结创办函数,那被叫做用户自定义函数。

1)为啥用函数:

  然后未来有贰个供给,让您总计’hello world’的长度,你怎么计算?

1 s1 = "hello world"
2 length = 0
3 for i in s1:
4     length = length+1
5 
6 print(length)

好了,成效达成了,卓殊周详。然后今后又有了1个供给,要计算其余一个字符串的长度,”hello
hx”.

 1 s1 = "hello world"
 2 length = 0
 3 for i in s1:
 4     length = length+1
 5 
 6 print(length)
 7 
 8 s2 = "hello eva"
 9 length = 0
10 for i in s2:
11     length = length+1
12 
13 print(length)   
结果:第一个程序输出是11,第二个程序输出是9。

那样确实能够兑现len方法的功力,可是总感到不是那么完美?为何吗?

首先,此前假设大家履行len方法就足以平昔得到一个字符串的长短了,今后为了贯彻平等的机能大家把相同的代码写了好多遍
—— 代码冗余

其次,此前我们只写两句话读起来也很不难,一看就清楚那两句代码是在盘算长度,不过恰恰的代码却不那么不难读懂
—— 可读性差

print(len(s1))
print(len(s2))

函数的重回值

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

#函数调用
str_len = mylen()      由于没有返回值,所以str_len接收到的是None,所以打印的也是None
print('str_len : %s'%str_len)

设若你执行那段代码,得到的str_len
值为None,那表明大家那段代码什么也从未给你回到。

那如何让它也想len函数一样重临值呢?

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen()
print('str_len : %s'%str_len)
结果:返回11

图片 327

 

 

 

  

 

初识函数定义与调用

  函数的有三中分歧的参数:

  普通参数

  暗中同意参数

  动态参数

概念函数的几点成分:

定义:def
关键词开首,空格之后接函数名号和圆括号(),最终还有三个”:”。

   def
是原则性的,不能够变,必须是连接的def四个字母,无法分别。。。它们要接近相爱的在一起。

   空格
为了将def关键字和函数名分别,必须空(四声),当然你能够空2格、3格或许您想空多少都行,但符合规律人如故空1格。

   函数名:函数名只好分包字符串、下划线和数字且不可能以数字开首。即便函数名能够任由起,但我们给函数起名字恐怕要尽量不难,并能表明函数成效

   括号:是必须加的,先别问何故要有括号,同理可得丰盛括号就对了!

注释:每贰个函数都应该对效果和参数实行对应的认证,应该写在函数上面第壹行。以增长代码的可读性。

调用:就是 函数名() 要记得加上括号

#函数定义
def mylen(s1):
    """计算s1的长度"""
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen("hello world")
print('str_len : %s'%str_len) 

函数的传参

我们报告mylen函数要总结的字符串是哪个人,那些进程就叫做 传送参数,简称传参,咱俩调用函数时传递的这么些“hello
world”和定义函数时的s1正是参数

实到场形参

参数还有些:

我们调用函数时传递的那几个“hello
world”被喻为实际上参数,因为那个是实际上的要提交函数的剧情,简称实参。

概念函数时的s1,只是三个变量的名字,被誉为款式参数,因为在概念函数的时候它只是一个款式,表示那里有2个参数,简称形参。  

传送三个参数

参数能够传递三个,多少个参数之间用逗号分割。

def mymax(x,y):
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)

  

地方参数

  站在实参角度

    1.依照岗位传值

def mymax(x,y):
    #此时x=10,y=20
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)

    2.主要字参数

def mymax(x,y):
    #此时x = 20,y = 10
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(y = 10,x = 20)
print(ma)

    3.职位,关键字两种方式的混用

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)

  

      正确用法

      难题一:地点参数必须在显要字参数的眼下

      难题二:对于1个形参只好赋值三回    

  站在形參角度

    地方参数必须传值

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

#调用mymax不传递参数
ma = mymax()
print(ma)

#结果
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'

  

默许参数

    1.正常化使用

      使用方法

      为啥要有暗许参数:将转变比较小的值设置成暗中认可参数

    2.暗中同意参数的概念

def stu_info(name,sex = "male"):
    """打印学生信息函数,由于班中大部分学生都是男生,
        所以设置默认参数sex的默认值为'male'
    """
    print(name,sex)


stu_info('alex')
stu_info('eva','female')

  3.参数陷阱:默许参数是一个可变数据类型

def defult_param(a,l = []):
    l.append(a)
    print(l)

defult_param('alex')
defult_param('egon')

  

动态参数

  按职责传值多余的参数都由args统一接受,保存成一个元组的花样,

#*args (按岗位传参,元组)

#\*kwargs (按重要性字传参,字典)*

 

def mysum(*args):
    the_sum = 0
    for i in args:
        the_sum+=i
    return the_sum

the_sum = mysum(1,2,3,4)
print(the_sum)


-------------------------------------------------------------------------------------------


def stu_info(**kwargs):
    print(kwargs)
    print(kwargs['name'],kwargs['sex'])

stu_info(name = 'alex',sex = 'male')

函数使用小节 

概念函数的规则:

1.定义:def 关键词开头,空格之后接函数名称和圆括号()。
2.参数:圆括号用来接收参数。若传入多个参数,参数之间用逗号分割。
    参数可以定义多个,也可以不定义。
    参数有很多种,如果涉及到多种参数的定义,应始终遵循位置参数、*args、默认参数、**kwargs顺序定义。
    如上述定义过程中某参数类型缺省,其他参数依旧遵循上述排序
3.注释:函数的第一行语句应该添加注释。
4.函数体:函数内容以冒号起始,并且缩进。
5.返回值:return [表达式] 结束函数。不带表达式的return相当于返回 None

def 函数名(参数1,参数2,*args,默认参数,**kwargs):
        """注释:函数功能和参数说明"""
        函数体
        ……
        return 返回值  

调用函数的平整

1.函数名()
    函数名后面+圆括号就是函数的调用。
2.参数:
    圆括号用来接收参数。
    若传入多个参数:
        应按先位置传值,再按关键字传值
        具体的传入顺序应按照函数定义的参数情况而定
      

3.返回值
    如果函数有返回值,还应该定义“变量”接收返回值
    如果返回值有多个,也可以用多个变量来接收,变量数应和返回值数目一致

无返回值的情况:
函数名()

有返回值的情况:
变量 = 函数名()

多个变量接收多返回值:
变量1,变量2,... = 函数名()

  

 

  

 

函数的执行种种

咱俩只要求在函数的末尾加上2个return,return后边写上您要回去的值就足以了。

接下去,大家就来商讨一下那么些return的用法。

return关键字的机能

  return
是2个首要字,在pycharm里,你会看出它成为浅湖蓝了。你不能够不一字不差的把那个单词给背下来。

  那一个词翻译过来正是“再次来到”,所以大家管写在return前边的值叫“再次回到值”

要商讨重返值,大家还要通晓重临值有三种景况:分别是从未有过重回值、再次回到一个值、重临八个值

尚无重临值

  不写return的情事下,会暗中同意再次来到三个None:大家写的第三个函数,就从未写return,那就是从未重返值的一种情景。 

只写return,后边不写别的剧情,也会回来None,有的同学会奇怪,既然没有要重返的值,完全能够不写return,为何还要写个return呢?那里我们要说一下return的别的用法,正是万一相遇return,截至所有函数。  

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen()
print('str_len : %s'%str_len)

回来四个值

  能够回到任意几个、任意数据类型的值

def ret_demo1():                #返回值如下
    return 1                    #1
def ret_demo2():
    return 1,2                  #(1,2)
def ret_demo3():
    return ['a','b']            #['a','b']
def ret_demo4():
    return 1,[],                #(1,[])
def ret_demo5():
    return 1,(1,2),{'a':'b'}    #(1, (1, 2), {'a': 'b'}),以上都为一个值接收
def ret_demo6():       
   return 1,                   #(1,)返回的也是个元组   
c= ret_demo*()
print(c)
---------------------------------------------------------------------------
def ret_demo5():
    return 1,(1,2),{'a':'b'} 
a,b,c= ret_demo5()              #返回多个值,就用多个值接收 1 (1, 2) {'a': 'b'}
print(a,b,c)

 总计:当再次回到多少个值的时候正是个字符串,当重回多个值的时候是以元组的款型重临,若是return
‘a’,重返的正是a。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图