python基础问题记录


前言

本专栏主要记录python中一些语法问题。

一、python中类的注意点

  1. 类属性:在类中定义的属性
    在类中直接写明的变量是类属性,属于公共属性。

    • 访问:类属性可以通过类或者类的实例访问
    • 修改:通过类对象修改的属性,在后续新实例对象会修改,已经创建的实例对象不会修改。
  2. 方法:在类中定义的函数(方法)

    • 实例方法:self作为首个参数。
      • 通过实例对象调用时:自动将当前实例作为self传入。
      • 通过类调用时,需手动把类对象传递给self。
    • 类方法:使用装饰器@classmethod修饰。
      • 类方法内不可以直接调用实例方法,也不可以调用实例变量。
      • 类和实例都可以直接调用类方法。
    • 静态方法:@staticmethod 修饰,是一个 Python 的一个内置装饰器,用于定义静态方法。静态方法是类中的方法,与类的实例无关,也无法访问类的实例变量或其他实例方法。静态方法通过类名调用,而不是通过实例调用。
    • 特殊方法:前后有两个下划线“_名字_”,特殊方法一般在特殊时刻自动调用。如__init__会在创建对象时自动调用。
  3. 双下划线与单下划线
    双下划线的属性或者方法,只能在类中使用,在外部使用会直接报异常,单下划线开头的不建议外部使用,但实际仍可外部调用。

  4. 装饰器
    装饰器能够使得不影响原有函数功能的基础上,添加新的功能。

    • @property:可以将方法使用类似属性的方式调用。
    class MyClass: 
    	_name = 1
    	@property
    	def name(self):
          return self._name
    m = MyClass()
    print(m.name)
    
    • @属性名.setter给属性赋值

二、模块与包

1. 模块

模块化指将一个完整的程序分解为一个一个小的模块,通过将模块组合,搭建出一个完整的程序

  • 不采用模块化,统一将所有的代码编写到一个文件中
  • 采用模块化,将程序分别编写到多个文件中

模块化的优点:方便开发、方便维护、模块可复用

python中一个py文件就是一个模块,要想创建模块,实际上就是创建一个python文件

2. 包

包也是一个模块

普通的模块就是一个py文件,而包是一个文件夹

  • 当模块中代码过多时,或者一个模块需要被分解为多个模块时,这时就需要使用到包
  • 包中必须要一个一个 init.py文件,这个文件中导入有必要的内容,不要做没必要的运算
  • init.py相关内容:_init_.py 的作用
    • 标识包:_init_.py 文件的存在表明包含它的目录是一个包。没有这个文件的目录不会被 Python 解释器识别为包。

    • 执行初始化代码:当包被导入时,_init_.py 中的代码会自动执行。这可以用来初始化包、设置变量、导入子模块等。

    • 控制导入行为:可以在 _init_.py 中定义 _all_ 列表来控制 from package import * 语句的行为。

三、引用与值传递

看如下例子:


def fun(x):
    print("形参地址:", id(x))
    x = 2
    print("重新赋值后的地址:", id(x))


a = 1
print("实参地址:", id(a))
fun(a)

结果:
实参地址: 7585472
形参地址: 7585472
重新赋值后的地址: 7585504

a = [1]
print("实参地址:", id(a))
fun(a)

实参地址: 140322120738176
形参地址: 140322120738176
重新赋值后的地址: 7585504

可看出python中对于所有变量(包括不可变量与可变量)采用的都是引用(指针)传递。

我看到有人说不可变量之所以赋值后地址改变是为了保持不可变量不可修改这一特性,其实这个说法不能解释为什么像列表这种重新赋值地址也改变了。

个人认为之所以赋值改变地址,跟python的动态类型有关,声明跟修改变量表面相似。

再看一下列表的一个奇怪点:

a = [1]
b = [2]
print("实参地址:", id(a))
a = a + b
print("修改后地址:", id(a))
a += b
print("修改后地址:", id(a))

实参地址: 140018730381376
修改后地址: 140018749130368
修改后地址: 140018749130368

a = [1]
b = [2]
print("实参地址:", id(a))
c = a + b
print("修改后地址:", id(a))
print("修改后地址:", id(c))

实参地址: 140040257363776
修改后地址: 140040257363776
修改后地址: 140040276105344

可看出a = a + b 与 a += b是完全等价的相当于append,而c = a + b 这就是赋值,因此c的地址与a的地址不同

可看出列表使用+合并两个列表的方法跟赋值是不同的,其实这个相当于调用了append方法,是修改列表中的元素,不会更改引用地址。

总结

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值