python 基础杂谈(一)

目录

运算符

成员运算符

身份运算符

模块和包         

常用高阶函数

lambda函数

filter函数

map函数

reduce函数

类的属性和方法

继承 

多态

类的高级属性

类变量 VS 实例变量

实例方法

类方法

静态方法


 

运算符

成员运算符

in :指定序列中找到值返回True,否则返回False

not in:指定序列中没有找到值返回True,否则返回False

身份运算符

is:判断两个变量是否引用自同一个对象

is not:判断两个变量是否引用自同一个对象。

身份运算符 VS 比较运算符(==)

  1. ==:数值比较,is 内存地址比较
    a, b= "sunny" * 10, "sunny" * 10
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))
    a = b
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))

    a, b = [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))
    a = b
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))
    

  2. 在python中,在一定的范围内,值相同的数字和字符串共用相同的内存地址。对象属于小数据池中的数据,当对象被销毁,python只会将这个对象引用回收掉,然而内存数据还是存在的,当由其他对象引用到该值时,会发现新的对象的内存地址跟之前销毁的内存地址是一样的。
    a, b, c = 5, 5, 5.0
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))
    print("a == c : {}".format(a == c))
    print("a is c : {}".format(a is c))
    a = c
    print("a == c : {}".format(a == c))
    print("a is c : {}".format(a is c))
    print("=" * 10)

    python 基础杂谈(一)_第1张图片

  3. a, b = 500000000000, 500000000000
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))

  4. a, b= "sunny", "sunny"
    print("a == b : {}".format(a == b))
    print("a is b : {}".format(a is b))

模块和包         

模块就是程序,模块的名称就是不含.py后缀的文件名。

模块属性:

  • dir-列出对象的所有属性即方法
  • help-查看类,方法的帮助信息
  • __name__-模块的名称,直接运行该模块其名是__main__,在其他地方调用该模块,其名是模块的名称(这也是为啥在模块测试的时候,可以用if __name__ == "__main__",这样可保证在调用的时候if里的语句不运行,只有在直接运行的时候才运行)
  • __file__-模块的全路径

包的简介

  • 可以用来组织模块(可以包含其他模块的模块)
  • 目录必须包含文件__init__.py
  • 解决模块重名问题

__init__.py

  • 将一个文件夹变为一个包
  • 导入包实际上是导入它的__init__.py
  • 一般为空,可以批量导入所需的模块

存在相对路径导入的模块,是不能直接运行的。

指定别名:可以解决导入后的重名问题;也可以方便书写,例如import as np;*不支持指定别名

可以全局导入也可以局部导入。

第一次导入包会运行包下__init__.py的代码,第一次导入包下的模块,会先运行包下__init__.py中的代码(若该包及其下的模块没有被导入过),再运行该模块的代码(若该模块之前未被间接导入过)。当然只有第一次导入会运行,后面就不会再运行了。

python 基础杂谈(一)_第2张图片

__init__.py

print("start package test_package")
from . import a
print("end package test_package")

a.py

print("start a")
def s(a, b):
    return a + b
print(s(1, 2))
print("end a")

b.py

from . import a
print("test_package b")

test.py

import test_package.b

python 基础杂谈(一)_第3张图片

可以看出,调用test_package下的模块b,会先运行test_package下__init__.py的代码(由于__init__.py导入了a,会执行a中代码),再执行b中代码(虽然b中也导入了a,但是a已经在__init__.py文件中导入过了,这边不再执行)。

test.py

from test_package.a import s
import test_package.b

python 基础杂谈(一)_第4张图片

常用高阶函数

lambda函数

是一种表达式,创建内嵌的简单匿名函数

filter函数

用于对序列过滤,返回一个filter对象,其中包含对其执行函数时结果为真的所有元素。

filter(func, seq)#传入的函数可以是lambda函数,也可以是自定义函数。

def f(n):
    return n % 2 != 0

l = list(range(1, 10))
print("原始列表:    {}".format(l))
print("filter+函数,转换成列表: {}".format(list(filter(f, l))))

lf = filter(lambda n: n % 2 != 0, l)
print("filter+lambda函数,返回filter对象:    {}".format(lf))
print("filter+lambda函数,转换成列表:    {}".format(list(lf)))

map函数

创建一个列表,其中包含对指定序列包含的项执行指定函数返回的值。
map(func,sequence,...) #传入的可以是序列也可以是元组以及列表

def pow_number(l):
    res = []
    for x in l:
        res.append(x * x)
    return res

def f(n):
    return n * n

l = list(range(10))
print("函数调用:    {}".format(pow_number(l)))  # 函数调用
print("列表生成式:   {}".format([x * x for x in l]))  # 列表生成式
print("map+lambda函数,返回map对象:    {}".format(map(lambda n: n * n, l)))  # map+lambda函数
print("map+lambda函数:    {}".format(list(map(lambda n: n * n, l))))  # map+lambda函数
print("map+函数调用:    {}".format(list(map(f, l))))  # map + 函数调用

python 基础杂谈(一)_第5张图片

reduce函数

使用指定的函数将序列的前两个元素合二为一,再将结果与第三个元素合二为一,依次类推,直到处理完整个序列并得到的一个结果。 reduce(func, seq[, initial]) 等价于 func(func(func(seq[0],seq[1]), seq[2]), ...)。

from functools import reduce

def f(a, b):
    return a + b

l = list(range(10))
print("reduce+函数调用: {}".format(reduce(f, l)))
print("reduce+lambda函数: {}".format(reduce(lambda a, b: a + b, l)))

python 基础杂谈(一)_第6张图片

类的属性和方法

类名建议首字母大写,通常用驼峰规则命名。变量名建议小写,下划线隔开。类最基本的作用是封装。

构造函数:自动执行,可以不写return,此时返回类型是None,不能强制返回其他类型

self代表当前类的实例对象,self.name表示将name绑定到实例上,即该类有实例属性name,等号右边的name表示__init__()中的参数name。在访问该属性时可以使用创建的实例对象调用。tag是类属性。

class Cat(object):
    # 类属性
    tag = "Cat"
    
    def __init__(self, name):
        # 实例属性
        self.name = name

继承 

  • 一种类与类之间的关系
  • 使用已存在的类的定义作为基础建立新类
  • 新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类
  • 继承的关系: · 满足“A is B ”的关系就可以形成继承关系

一个对象是否是某个类的实例:issubclass(对象, 类),判断对象是否是类的实例,具有传递性。即若类是对象所属类的直接父类或间接父类均返回True

一个类是否是另一个类的子类:isinstance(类1, 类2),判断类1是否是类2 的子类,具有传递性。即若2是1的直接父类或间接父类均返回True

class Cat(object):
    # 类属性
    tag = "Cat"

    def __init__(self, name="o"):
        # 实例属性
        self.name = name


class PetCat(Cat):
    pass


pet_cat = PetCat()

print("PetCat 是 object 的子类: {}".format(issubclass(PetCat, object)))
print("pet_cat 是 Cat 的子类: {}".format(isinstance(pet_cat, Cat)))

  

类的多重继承 能不用就不用,用的话要用清晰 一个类有多个父类,就是多重继承 多重继承时,如果有重名的方法,只会调用第一个。

class CoutryProtectedMixin(object):
    def show(self):
        print("protected by country")


class ProtectedMixin(object):
    def show(self):
        print("protected by province")


class Cat(ProtectedMixin, CoutryProtectedMixin):
    pass


cat = Cat()
cat.show()

多态

  • 定义:意味着允许不同类的对象对同一消息作出不同的响应
  • 必要条件:
    • 满足继承关系
    • 父类引用指向子类对象(必须有方法的重写)
class Cat(object):
    def __init__(self, name):
        self.name = name
        print("Cat init")

    def show(self):
        print("name: {}".format(self.name))


class PetCat(Cat):
    def __init__(self, name, color):
        super().__init__(name)
        self.color = color
        print("PetCat init")

    def show(self):
        print("name: {}, color: {}".format(self.name, self.color))


cat = Cat("huanghuang")
cat.show()
print("=" * 10)
pet_cat = PetCat("huahua", "blue")
pet_cat.show()

python 基础杂谈(一)_第7张图片

类的高级属性

@property:将类的方法当做属性来使用,使用时写在方法的前面,且调用被修饰的方法时,只能当属性调用,即不加(),否则执行完方法体后会抛出异常,同时使用@property来修饰的方法不能带参数

@方法名.setter 当属性设置为私有属性时,在外部不可以直接修改,因此可以同时使用@property 和 @方法名.setter 从而可以修改私有属性的值 可以理解为@property表示只读,@property 和@方法名.setter表示可读可写 setter装饰器必须在property的后面,且两个被修饰的属性(函数)名称必须保持一致。

class Cat(object):
    def __init__(self, age):
        self.__age = age

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        self.__age = age


cat = Cat(8)
rest = cat.age
print("我{}岁了".format(rest))
cat.age = 10
rest = cat.age
print("我{}岁了".format(rest))

__slots__:为指定的类设置一个静态的列表,为属性很少的类节约空间,__slots__方法用元组定义允许绑定的属性名称和方法名而不是列表,使用后不允许为实例添加新的属性或方法,但是__slots__只对本类(即父类有效),并不影响子类,即子类依旧可以添加新的属性,当子类中也定义__slots___时,子类的静态列表拼上父类的静态列表就是允许子类实例化使用的属性。

__slots__只对本类(即父类有效),并不影响子类,即子类依旧可以添加新的属性

类变量 VS 实例变量

实例方法

      实例方法关联的是对象,实例方法通常用来操作实例变量,定义实例方法形参要多写一个self(也可以是别的,建议self),在传参数时不需要给self传值,self代表的是调用它的对象。

       在实例方法中访问实例变量,用self.变量名访问;访问类变量,用类名.变量名,或者self.__class__.变量名。

       在类的外部访问实例变量,可以用对象名.变量名;在类的外部访问类变量,可以用类名.变量名。

类方法

       类方法关联的是类,类方法通常用来操作类变量,定义加@classmothod,形参要多写一个cls(也可以是别的,建议cls),cls代表的是调用的类,类方法不会被自动调用

       在类方法中访问类变量,用cls.变量名访问;可以用类也可以用对象调用类方法(但是不建议用对象调用类方法,毕竟逻辑不符),在类方法中不可以访问实例变量。

静态方法

       静态方法定义加@staticmethod,不强制多传一个形参。可以用类也可以用对象调用静态方法,静态方法也可以访问类变量,和类方法没啥太多区别,在静态方法中不可以访问实例变量。不推荐用静态方法,因为静态方法不是很能体现面向对象的特点。

python 基础杂谈(一)_第8张图片

通过在方法名前加__将方法变为私有的,在外部不可以通过对象名/类名.__方法名访问。python在类外部可以通过对象名.变量名添加实例变量。严格来讲python并没有真正的私有变量,因为可以通过对象名._类名__变量名。

python 基础杂谈(一)_第9张图片

 

继承:

       调用父类的方法可以通过super。

https://pan.baidu.com/s/1ebpbzN6YLnUzCGxO9V-MGg

 

 

 

 

 

 

 

 

你可能感兴趣的:(python,python)