写点什么

Python 进阶 (九)Python 陷阱:Nonetype

  • 2022 年 10 月 10 日
    江苏
  • 本文字数:1387 字

    阅读完需:约 5 分钟

Python进阶(九)Python陷阱:Nonetype

今天解决一位网友的问题,内容如下:请教代码问题


def calc_prod(lst):    def ff():        print map(lambda x:x*x,lst)    return ff
f = calc_prod([1, 2, 3, 4])print f()
复制代码


结果:


[1, 4, 9, 16]None
复制代码


这样写输出为什么有 None?针对这一问题,自己在 IDEA 中进行了调试,发现果然多输出了一行 None。出现这一现象确实很令人费解。


自己写了简单的测试语句,如下:


b = print(5)print(b)
复制代码


通过断点调试,内容如下:



发现 b 的值确实为 None,且其类型为 NoneType。


什么是 Nonetype?


要理解这个,首先要理解Python对象,python对象具有三个特性:身份、类型、值。


这三个特性在对象创建时被赋值。只有值可以改变,其他只读。类型本身也是对象。


NullNonePython的特殊类型,Null对象或者是None Type,它只有一个值None


它不支持任何运算也没有任何内建方法。None和任何其他的数据类型比较永远返回False


None有自己的数据类型NoneType。你可以将None复制给任何变量,但是你不能创建其他NoneType对象。


一句话总结:Null对象是python对象,又叫做NoneTypeNone是这个对象的值。


看过了NoneType的解释,之所以出现None就很好理解了。


NoneType之所以出现是因为定义了一个变量或函数,却没有值或者返回值,因此会默认值为None


而在上面的程序中,虽然高阶函数 calc_prod()有返回值 ff,但是 ff()却没有返回值,则传递到外层函数 calc_prod()同样没有返回值,故输出了None。 若代码改为如下所示,则可以完美实现列表的输出。


def calc_prod(lst):    def ff():        return map(lambda x:x*x,lst)    return ff
f = calc_prod([1, 2, 3, 4]) print(f())
复制代码


注意⚠️:一个实例的私有属性就是以__开头的属性,无法被外部访问。那这些属性定义有什么用?


虽然私有属性无法从外部访问,但是,从类的内部是可以访问的。除了可以定义实例的属性外,还可以定义实例的方法。


实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的。


class Person(object):    def __init__(self, name):        self.__name = name
def get_name(self): return self.__name
复制代码


get_name(self) 就是一个实例方法,它的第一个参数是 self。__init__(self, name)其实也可看做是一个特殊的实例方法。调用实例方法必须在实例上调用:


p1 = Person('Bob')print p1.get_name()  # self不需要显式传入# => Bob
复制代码


在实例方法内部,可以访问所有实例属性,这样,如果外部需要访问私有属性,可以通过方法调用获得,这种数据封装的形式除了能保护内部数据一致性外,还可以简化外部调用的难度。


请给 Person 类增加一个私有属性 __score,表示分数,再增加一个实例方法 get_grade(),能根据 __score 的值分别返回 A-优秀, B-及格, C-不及格三档。


注意 get_grade()是实例方法,第一个参数为 self。


参考代码:


class Person(object):
def __init__(self, name, score): self.__name = name self.__score = score
def get_grade(self): if self.__score >= 80: return 'A' if self.__score >= 60: return 'B' return 'C'
p1 = Person('Bob', 90)p2 = Person('Alice', 65)p3 = Person('Tim', 48)
print p1.get_grade()print p2.get_grade()print p3.get_grade()
复制代码


运行结果



发布于: 刚刚阅读数: 7
用户头像

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
Python进阶(九)Python陷阱:Nonetype_Python_No Silver Bullet_InfoQ写作社区