Python语言基础考察一
本文重点讨论Python的语言特性 & 类方法 & 鸭子类型
一、动态类型or静态类型?强类型or弱类型?
首先公布答案:Python是 动态 强类型语言(不少人以为是弱类型,其实是强类型)。下面是解析:
- 正所谓“动态语言一直爽,代码重构火葬场”,那么到底什么是动态类型,什么又是静态类型呢?
答:动态类型和静态类型指的是代码在编译期还是运行期确定对象的类型。 - 那么什么是强类型和弱类型呢?
答:衡量一个语言是不是强类型还是弱类型看其是否发生隐式类型转换,让我们来举个栗子:
/*下文是在浏览器中选择console运行的JavaScript代码的结果代码:*/
1+'1'
"11"
/*这个地方发生了隐式类型转换,一个字符串类型和数值类型进行相加得到了一个新的字符串
但是在Python里这样做会报错的
二、Python语言的性能/特点
下面是Python语言的一些优点:
1、胶水语言,轮子多,应用广泛
2、语言灵活,生产力高
3、目前还是存在性能问题(例如Gil全局解释器锁问题还是没有很好的解决方法)
4、代码维护问题(主要在于python2/3不兼容,像豆瓣等一些大型网站之前用python2写的代码现在在python3中可能会存在诸多问题,不仅仅是简单的pirint、xrange几个函数的问题,而是涉及到拓展库的方法调用,源代码的更新等等问题)
注释:
(1)胶水语言指的是:可以调用别的语言编写的功能模块,将他们有机的结合在一起形成更高效的新程序。
例如Python可以把C++、Java写的模块轻松结合起来协同工作,这样就能把c++的针对底层,java的面向对象两大优势统一到一个完整的程序中来(虽然我还没用过这个功能 =_= ,但是听起来就很牛啦)
(2)轮子多:Python社区创造了一大堆各种各样的Python库。在他们的帮助下,你可以管理文档,执行单元测试、数据库、web浏览器、电子邮件、密码学、图形用户界面和更多的东西。所有东西包括在标准库,然而,除了它,还有很多其他的库
顺便扯个蛋:别以为python是一门很新的语言,其实python是1989年Guido圣诞节期间为了打发圣诞节无聊的时间而写的……(汗颜,原来大佬们无聊的时候干这个),而为人所熟知的Java是1995年Sun公司重新开发搁置已久的Oak语言并将其更名为Java的,所以论起辈分,python还是Java的前辈~
三、init、new、__class__的作用以及联系
1、init:
(1)构建初始化函数,给类的实例进行初始化属性,可以不需要返回值
(2)在创建类的实例时系统自动调用
(3)自定义类如果不定义的话,默认调用父类的初始化函数
class Student(object):
def __init__(self,name):
self.name = name
print("__init__")
class StudentOne(Student):
pass
s = StudentOne("Tom")
运行结果为:
__init__
2、new:
(1)用所给的类创建一个对象(或者说实例),并返回这个对象
(2)因为是给类创建一个实例的,所以至少传一个参数cls,参数cls代表要实例化的类,此参数由Python解释器自动提供
(3)只有创建了实例才有初始化这一系列的操作,所以这个是最先调用的
(4)创建了实例要返回这个实例,所以要有返回值。return 返回父类或者object的__new__的实例
class Student(object):
def __init__(self, name):
self.name = name
print("__init__" + name)
def __new__(cls, *args, **kwargs):
print('__new__')
return object.__new__(cls) #注意一定要有返回值
def func(self):
print(self.name)
class StudentOne(Student):
def __new__(cls, *args, **kwargs):
print("__new__" + str(args))
return Student.__new__(cls) #注意一定要有返回值
s = StudentOne("Tom")
运行结果为:
__new__('Tom',)
__new__
__init__Tom
注意:
(1)__new__方法中使用的是*args不定参数传参,涉及到了元组的解包问题,所以在打印的时候需要使用str类型转换才可以打印出来。
(2)__new__的方法是先于__init__调用的。
3、class:
(1)此方法功能与type()一样,都是用来查看对象的类
(2)__class__可以套用
class Student(object):
def __init__(self,name):
self.name = name
s = Student('Tom')
print(type(s))
print(s.__class__)
print(s.__class__.__class__)
运行结果为:
<class '__main__.Student'>
<class '__main__.Student'>
<class 'type'>
注意:
(1)__ class __ 可以套用
(2)为什么 s. __ class__ .__class__打印出来的是‘type’呢?原因是python中一切都是对象,而对象又可以分为三类,如下:
- 第一类:type自成一类,type是自己的对象(可以实例化自己)。object 是 type 的实例,而 type 继承自 object。
- 第二类:list、str、Student…类会继承object,list、str、Student…等父类,同时也是type的对象,可以进行 type(xxx) 的操作。object是所有的基类(一切都继承object)
- 第三类:生成的对象
四、鸭子类型(动态语言)
当一只鸟走起来像鸭子,游泳像鸭子,叫起来也像鸭子,那这只鸟就可以被称为鸭子(我满脑子都是《猫和老鼠》里面Tom学鸭子叫的画面=_=……)
所谓的“鸭子类型”有以下几个要点:
- 关注的点在于对象的行为,而不是类型(duck typing)
- 比如file、StringIO、socket 对象都支持 read/write 方法
- 再比如定义了__iter__魔术方法的对象可以用 for 迭代
所以,鸭子类型更关注的的是接口而非类型
代码演示如下:
class Duck(object):
def quack(self):
print("gua gua ")
class Person(object):
def quack(self):
print("我是人,但是我可以 gua gua ")
def in_the_forest(duck):
duck.quack()
def game():
Donald = Duck()
John = Person()
for _ in [Donald,John]:
in_the_forest(_)
if __name__ == '__main__':
game()
运行结果:
gua gua
我是人,但是我可以 gua gua
这里就是鸭子类型的演示,只要有同样的接口不管是什么类型都可以调用接口
下期预告:
- monkey path
- 自省
- 列表和字典的推导
- Python之禅
嘿嘿,I am very glateful that 你看到这里了哦~thks