Python学习难点和易错点

 

这是我的第一个博客,是对之前学习的Python进行进一步的深入理解的过程中遇到的一些比较有意思的地方。

注:本文基于python 2.x

 

1、__new__()和__init__():

__new__()可看做是构造函数,正常情况需返回类实例(一般是通过super(currentClass,  cls).__new__(cls)调用返回类实例),如果其不返回类实例,则__init__()不会被调用;而当__new__()返回类实例,__init__()则作为初始化函数,对类实例属性进行设置等,其接收的参数与__new__()一致,也即__new__()和__init__()的函数定义的参数必须一致,否则会报错;

具体可参考:官方文档对__new__和__init__的描述Python 之 __new__() 方法与实例化

 

2、Python的函数参数传递是将引用对象地址的一份复制赋值给形参,若在函数内改变形参的指向(即对形参重新赋值),则不会影响原指向内存的内容。

相关参考:https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference

例如:

def try_to_change_list_reference(the_list):
	print 'got', the_list
	the_list = ['and', 'we', 'can', 'not', 'lie']
	print 'set to', the_list
	
outer_list = ['we', 'like', 'proper', 'English']
print 'before, outer_list = ', outer_list
try_to_change_list_reference(outer_list)
print 'after, outer_list = ', outer_list

运行结果为:

before, outer_list =  ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list =  ['we', 'like', 'proper', 'English']

 

4、对于metaclass的理解:

(1)类用于创建对象,而metaclass用于创建类;

(2)在python2中,使用__metaclass__指明一个类的metaclass,而python3中则在类定义时使用metaclass指出,形如

“class Foo(object, metaclass=something):”;

(3)python解释器根据以下顺序确定一个类的metaclass:
1)、在类中对__metaclass__赋值;
2)、如果该类有至少一个父类,则使用父类的metaclass(即首先寻找父类的__class__,如果没找到,则使用父类的类型)
3)、如果该类没有父类,则在全局变量中寻找__metaclass__;
4)、如果全局变量没有__metaclass__,则使用types.ClassType

(4)__metaclass__必须为callable,并且其必须能创建类(即其需要调用type()或者继承type类,type类是一个非常特殊的类,其metaclass为自身);

(5)如果一个类的metaclass也是一个类,则metaclass.__new__()需调用type.__new__()去创建一个类。

具体可以参考:对metaclass的完美讲解官方文档对于metaclass的解释

5、classmethod和staticmethod相关内容:https://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

6、对于@staticmethod装饰的静态方法,对于调用它的类或者实例一无所知,也即该静态方法内无法访问它所在的类的类变量或者实例变量。

7、类变量VS实例变量:每个实例将获得类变量的一份拷贝,即变量内容相同而地址不同,如果对某个实例的类变量重新赋值,不会影响到该类其他实例的这个类变量值。

例如:

class Person:
    name="aaa"

p1=Person()
p2=Person()
p1.name="bbb"
print p1.name  # bbb
print p2.name  # aaa
print Person.name  # aaa

8、字典推导式:d = {key: value for (key, value) in iterable}
e.g:myList = [('a',1), ('b',2), ('c',3)]
    d = {key: value for (key, value) in myList}
对比列表推导式:[x**2 for x in range(10) if x % 2 == 0]

9、单下划线和双下划线:
a、在一个模块中,单下划线开头的变量和函数被默认当中内部私有成员,当使用from a_module import *时,这些变量和函数不会被导入,但如果使用import a_module导入时,仍然可以用a_module._var访问;
b、如果类成员使用双下划线开头命名,则Python会自动将其名称改为_classname__var,这是为了避免该成员的名称与子类中的名称冲突;
c、而类似于__init__为Python具有特别含义的标识符,Python 官方推荐永远不要将这样的命名方式应用于自己的变量或函数

具体可以参考:

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值