python中的一些小知识点

目录

init方法

python中的yield和return

def driver(): 和 def driver(self)的区别

with语句

python中的魔法函数

python私有方法

python中的 import和 from 导包的时候有什么区别

python的生成器和迭代器

迭代器

生成器

测试中yield的使用


init方法

init方法和Java中的构造函数非常像,在类创建实例时进行调用,下面的代码中self指向的是类本身。

class Student:
    def __init__(self,number):
        self.number=number 
    def student_number(self):
        print('number:',self.number)
        
student=Student(34)
student.student_number()

参考:

Python笔记 class中的__init__()方法_python class init-优快云博客

python中的yield和return

  • yield在一段程序中可以看做return。return在程序中返回某个值,返回之后就不在往下执行了,而yield在返回值后会继续执行函数体内代码
  • yield 是一个生成器函数,返回的是一个迭代器

参考:

python中的yield和return—迭代器和生成器_python 迭代器 return-优快云博客

python中yield的用法详解——最简单,最清晰的解释_yield python-优快云博客

在 Python 中,yield 是一个关键字,用于定义生成器(generator)函数。生成器是一种特殊的迭代器,它允许你逐个产生值,而不是一次性计算并返回一个列表或其它类型的数据结构。使用 yield 的函数被称为生成器函数。

生成器函数与普通函数的主要区别在于,当生成器函数执行到 yield 表达式时,它会返回当前的值给调用者,并且暂停函数的执行,保留当前函数的状态,包括局部变量和参数等。当生成器函数再次被调用时,它会从上次暂停的地方继续执行。

以下是一些关于 yield 的关键点:

  1. 逐个产生值:生成器可以在每次迭代时产生一个值,而不是一次性返回所有值。

  2. 节省内存:由于生成器不会一次性生成所有值,它们在处理大量数据时可以节省内存。

  3. 状态保持:生成器函数在 yield 表达式处暂停和恢复,保留所有局部状态。

  4. 使用 next() 函数:要获取生成器的下一个值,可以使用 next() 函数或在 for 循环中直接迭代。

  5. 生成器表达式:除了生成器函数,Python 还支持生成器表达式,这是一种使用圆括号而不是花括号定义的简洁方式。

def driver():def driver(self)的区别

  1. 全局函数 def driver():

    • 这是一个没有接收任何参数的全局函数。
    • 由于它是一个全局函数,所以它不属于任何类,可以被任何其他函数或类直接调用。
    • 在使用 pytest 的上下文中,这种函数可以直接用作 fixture,通过添加 @pytest.fixture 装饰器来声明。
  2. 类方法 def driver(self):

    • 这是一个类的方法,它的第一个参数是 self,这是类实例的引用。
    • 它同样定义了一个生成器,用于创建 WebDriver 实例,并通过 yield 返回。
    • 由于它是一个方法,所以它必须在类的上下文中被调用,并且需要一个类的实例或者使用 @staticmethod 或 @classmethod 装饰器来避免需要类的实例。
    • 在 pytest 中,如果你想将这个方法用作 fixture,你需要将它定义在一个测试类中,并且使用 @pytest.fixture 装饰器。但是,通常 fixture 不需要 self 参数,除非你需要在 fixture 中访问测试类的其他方法或属性

pytest 的上下文中,fixture 通常不需要类上下文,因此更常见的是使用全局函数作为 fixture

总结:没有self的是全局函数,不属于任何类,带有self的是属于一个类

with语句

  with语句在Python中通常用于实现上下文管理协议,它允许你以一种优雅的方式处理资源的获取和释放。这种语句通常用于文件操作、锁的获取与释放、数据库连接等场景,以确保即使在发生异常的情况下,资源也能被正确地清理。

       with语句的基本用法

with expression as variable:
    # 代码块
    # 这里的代码可以使用variable来访问expression的结果
    # 当退出这个代码块时,会自动执行清理操作

如下面这段代码

class TestWindowHandle:
    @allure.description("登录")
 
    def test_switch_window_handles(self, driver):
        with allure.step("登录"):
            LoginPage().login(driver, "jay")
            sleep(3)
            add_img_2_report(driver, "登录")

     

with allure.step("步骤名称"):使用了Allure框架的step装饰器,它并不是Python标准库的一部分,而是Allure框架提供的一个上下文管理器,用于在测试报告中创建一个新的步骤。当进入with代码块时,Allure框架会记录步骤的开始,当退出with代码块时,无论是否发生异常,Allure框架都会记录步骤的结束。这样,测试报告就可以清晰地展示每个测试步骤的执行情况。

python中的魔法函数

Python 中的 __ 函数,通常称为 "魔法方法"(magic methods)或 "双下方法"(dunder methods),是一些具有特殊意义的函数,它们通常不需要直接调用,而是由 Python 解释器在特定的情况下自动调用。这些方法允许开发者定义或修改类的默认行为。以下是一些常见的魔法方法:

  • __init__(self, ...): 类的构造器,当一个实例被创建时调用,用于初始化对象。
  • __del__(self): 类的析构器,当一个实例被销毁时调用。
  • __str__(self): 当使用 print() 函数或 str() 时调用,返回对象的字符串表示。
  • __repr__(self): 当使用 repr() 函数时调用,返回对象的官方字符串表示,通常可以用来重新创建该对象。
  • __len__(self): 当使用 len() 函数时调用,返回容器类型的长度。
  • __getitem__(self, key): 用于获取序列的元素,如 obj[key]
  • __setitem__(self, key, value): 用于设置序列的元素,如 obj[key] = value
  • __delitem__(self, key): 用于删除序列的元素,如 del obj[key]
  • __iter__(self): 返回对象的迭代器,使得对象可以使用在迭代上下文中,如 for x in obj
  • __next__(self): 返回迭代器的下一个元素。
  • __call__(self, ...): 允许一个类的实例像函数那样被调用,如 obj()

普通函数是用户定义的常规函数,它们没有特殊的名字前缀,可以在任何需要的地方被显式调用。普通函数没有上述魔法方法的特殊行为,它们的行为完全由函数体内的代码决定。

下面使用代码举例

  • __init__ 方法:这是类的构造器,用于初始化新创建的对象。
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 使用
person = Person("Alice", 30)
  • __len__ 方法:当使用 len() 函数时,这个方法会被调用,用于返回容器类型的长度
class MyList:
    def __init__(self, elements):
        self.elements = elements
    def __len__(self):
        return len(self.elements)

# 使用
my_list = MyList([1, 2, 3])
print(len(my_list))  # 输出: 3
  • __getitem__ 方法:用于获取序列的元素,如 obj[key]
class MyList:
    def __init__(self, elements):
        self.elements = elements
    def __getitem__(self, index):
        return self.elements[index]

# 使用
my_list = MyList([1, 2, 3])
print(my_list[1])  # 输出: 2

注意:不是函数前面有__就是魔法函数了!!!

普通的私有方法,虽然也使用双下划线开头,但不会以双下划线结尾,例如 _get_private_data。这种命名约定是 Python 中的一个惯例,用来指示这个方法是私有的,不应该被类的外部直接调用。

总结:只有在函数名前后都有双下划线的才是魔法方法,如果只在函数名前有双下划线是代表类的私有方法

所以我们下面来看看python中的私有方法。

python私有方法

在 Python 中,私有方法或属性的命名规则是通过在名称前加上双下划线 __ 来实现的。这种命名约定告诉 Python 解释器和其他开发者,这些方法或属性不应该被类的外部直接访问或修改。Python 通过名称改编(name mangling)的技术来实现私有属性的封装。

以下是 Python 中私有方法的命名规则:

  1. 双下划线前缀:私有方法的名称以 __ 开头,例如 __private_method

  2. 名称改编:Python 解释器会自动将类中的私有方法名称改编为 _ClassName__private_method 的形式。这意味着即使子类中有相同名称的方法,它们也不会冲突,因为名称已经被改编了。

  3. 不可直接访问:按照惯例,外部代码不应该访问或调用私有方法。如果外部代码尝试访问私有方法,它将不会找到该方法,除非它知道改编后的名称。

  4. 类内部访问:即使方法被标记为私有,它们仍然可以在类的内部被访问和调用,就像普通的实例方法一样。

  5. 子类继承:私有方法可以被子类继承,但子类中的代码也不能直接访问它们,除非使用名称改编后的名称。

  6. 不是强制私有:Python 中的私有属性和方法只是一种命名约定,并不是强制的访问控制。它们更多地是作为文档和指导,告诉其他开发者这些属性和方法不应该被外部访问

举例说明

class MyClass:
    def __init__(self):
        self.__private_attribute = 42

    def __private_method(self):
        print("I'm a private method!")

    def public_method(self):
        print("I'm a public method.")
        self.__private_method()  # 从公共方法中调用私有方法

# 实例化并尝试调用私有方法
my_instance = MyClass()
my_instance.public_method()  # 正常工作
# my_instance.__private_method()  # 这将引发 AttributeError,因为外部不能直接调用私有方法

在这个例子中,__private_method 是一个私有方法,它只能在 MyClass 类的内部被调用。尝试从类的外部直接调用它将会导致 AttributeError

python中的 import和 from 导包的时候有什么区别

Python3基础之import和from import的用法和区别_from import和直接import的区别-优快云博客

还没有总结~~

python的生成器和迭代器

迭代器

迭代这个词,我们可以理解为循环访问一个对象,这个对象需要是可迭代的。像python中的字符串、列表、元组、字典这些都是可迭代的。迭代器是一个可以记住遍历的位置的对象,是从可迭代对象的第一个元素开始访问,直到所有的元素都被访问完就结束。迭代器有两个基本的方法iter和next

  • iter

    iter用来创建可迭代对象

  • next

    输出迭代器的下一个元素

menu_list = ["a", "b", "c"]
iter_menu_list = iter(menu_list)
for x in iter_menu_list:
    print(x)

这样看起来是不是和普通的循环一样,但是不同的是迭代器里面有next函数,可以使用next函数打印迭代器的下一个元素,然后再循环这个迭代器对象

menu_list = ["a", "b", "c"]
iter_menu_list = iter(menu_list)
print(next(iter_menu_list))
for x in iter_menu_list:
    print(x)

这时候的输出和上面的一样

为什么没有打印出两次 呢?

因为第一次使用next的时候,a 已经访问过了,可以将next看做一个指针,开始的时候指针在最前面,之后使用一次next就往后移动一位。

这就是迭代器和普通循环的区别。

生成器

    Python 中的生成器(Generator)是一种特殊的迭代器,它允许你逐个产生值,而不是一次性创建并存储所有值。生成器通常通过使用 yield 语句来实现,这使得函数在每次迭代时返回一个值,并且在下一次迭代时从上次停止的地方继续执行,而不是从头开始。

def menu():
    print("开始执行")
    menu_list = ["a", "b", "c"]
    for m in menu_list:
        print("当前是:",m)
        yield m
        print("下一个")
print_menu = menu()
print(next(print_menu))

这段程序的执行结果是

这样看来是不是yield和return一样

但是当我们加入一行next后,就可以看到区别了

代码如下:

def menu():
    print("开始执行")
    menu_list = ["a", "b", "c"]
    for m in menu_list:
        print("当前是:",m)
        yield m
        print("下一个")
print_menu = menu()
print(next(print_menu))
print(next(print_menu))

这个结果里为什么会出现”下一个“呢?其实当我们执行第二个next的时候,是从print("下一个")开始的,再进入menu_list的循环里。这就跟我们之前学习的编程思想有点区别了,之前学习的都是执行就直接执行完了,不会像生成器一样,还能让函数暂停的。

测试中yield的使用

yield这行以及这行前面的是测试用例的前置部分,yield这行后面的就是测试用例的后置部分。我们可以在前置里放一些数据库查询、登录等等信息,后置也可以放数据库操作之类的清理数据的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值