py面向对象特性:继承、封装、多态、鸭子模型、魔法方法

本文主要是介绍py面向对象特性:继承、封装、多态、鸭子模型、魔法方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

面向对象三大特性

  • 1、面向对象特性之继承
    • 1.1 继承的基本使用
    • 1.2 demo
    • 1.3 重写父类方法和调用父类方法 (类对象调用方法相当于 函数化调用,注意 位置传参)
      • 1.3.1 重写
      • 1.3.2 调用
      • 1.3.3 面试题:作用域问题
      • 1.3.4 继承案例
      • 1.3.5 多重继承
      • 1.4 判断类的继承关系:type 和isinstance方法
      • 1.5 查看实例的所有属性:dir()方法和__dict__属性
  • 2、面向对象特性之封装
    • 2.1 **封装概述**
    • 2.1.1 **封装原则**
    • 2.1.2 **封装好处**
    • 2.2 私有属性
      • 2.2.1 私有属性定义
      • 2.2.2 私有属性完整 demo
      • 2.2.3 私有属性总结
    • 2.3 单下划线、双下划线、头尾双下划线说明
    • 2.4 私有方法
    • 2.5 property属性装饰器
  • 3、面向对象特性之多态
    • 3.1 多态的使用
    • 3.2 多态发生的前提:
    • 3.3 鸭子模型 (动态类语言)
  • 4、魔法方法
    • 4.1 \_\_new\_\_ () 构造方法
    • 4.2 \_\_init_\_() 初始化方法
    • 4.3 \_\_str\_\_()
    • 4.4 \__call\_\_()
    • 4.5 \__del\_\_() 构析方法
    • 4.6 \_\_getitem_\_() 字典化操作 属性
    • 4.7 \_\_getattr_\_() attr 句点符 操作属性
    • 4.8 \_\_eq_\_() 用于两个对象比较
    • 4.9 \_\_len_\_()
  • 5、反射

1、面向对象特性之继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。通过继承创建的新类称为子类派生类,被继承的类称为基类父类超类

class 派生类名(基类名)...

1.1 继承的基本使用

继承者是被继承者的特殊化,它除了拥有被继承者的特性外,还拥有自己独有得特性。例如猫有抓老鼠、爬树等其他动物没有的特性。同时在继承关系中,继承者完全可以替换被继承者,反之则不可以,例如我们可以说猫是动物,但不能说动物是猫就是这个道理,其实对于这个我们将其称之为“向上转型”。

继承定义了类如何相互关联,共享特性。对于若干个相同或者相识的类,我们可以抽象出他们共有的行为或者属相并将其定义成一个父类或者超类,然后用这些类继承该父类,他们不仅可以拥有父类的属性、方法还可以定义自己独有的属性或者方法。

同时在使用继承时需要记住三句话:

  • 1、子类拥有父类非私有化的属性和方法。
  • 2、子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
  • 3、子类可以用自己的方式实现父类的方法。(重写)。

1.2 demo

  • 无继承
class Dog:def eat(self):print("eating...")def sleep(self):print("sleep...")def swimming(self):print("swimming...")class Cat:def eat(self):print("eating...")def sleep(self):print("sleep...")def climb_tree(self):print("climb_tree...")
  • 有继承
class Animal:def eat(self):print("eating...")def sleep(self):print("sleep...")class Dog(Animal):def swimming(self):print("goupaoshi...")class Cat(Animal):def climb_tree(self):print("climb_tree...")alex = Dog()
alex.run()

1.3 重写父类方法和调用父类方法 (类对象调用方法相当于 函数化调用,注意 位置传参)

1.3.1 重写

class Animal:def eat(self):print('eating ...')def sleep(self):print('sleeping ...')class Dog(Animal):def swimming(self):print('狗刨式...')def sleep(self):print('趴着睡')alex = Dog()
alex.sleep()

1.3.2 调用

super().方法(参数)

  • 无参
class Animal:def eat(self):print('eating ...')def sleep(self):print('sleeping ...')class Dog(Animal):def swimming(self):print('狗刨式...')def sleep(self):# 方式1:硬编码,不推荐.# 父类对象调用 父类对象.方法(self,其他参数)# Animal.sleep(self)    # 类对象调用方法相当于 函数化调用,注意 位置传参# 方式2:super关键字# super(子类对象,self).方法(参数)or super().方法(参数)# super(Dog, self).sleep()    # 不推荐,还是存在硬编码super().sleep()      # 推荐!!  super() 实例化对象.方法  解决硬编码print('趴着睡')alex = Dog()
alex.sleep()
  • 有参

继承的初始化的参数务必对齐

class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef sleep(self):print("基类sleep...")class TL(Person):# def __init__(self, name, age, dep):#     self.name = name#     self.age = age#     self.dep = dep# 注意:继承的初始化的参数务必对齐def __init__(self, name, age, dep):super().__init__(name, age)self.dep = depyuan = TL("yuan", 18, "游戏部")yuan.sleep()
print(yuan.dep)

1.3.3 面试题:作用域问题

  • 输出值为多少?

class A:x = 100def __int__(self, x):self.x = xdef foo(self):print(self.x)class B(A):x = 12b = B()
b.foo()# 12

1.3.4 继承案例

  • 案例:电商项目的结算功能

继承、调用思想之应用,解耦发版代码,每次活动发布都不用修改源码

import random
import datetimeprint('''1、海尔冰箱 单价3000元;2、西门子洗衣机 单价5000元;3、芝华士沙发 单价6000元''')goods = {1: ("海尔冰箱", 3000), 2: ("西门子洗衣机", 5000), 3: ("芝华士沙发", 6000)}# 结账类
class Bill(object):def __init__(self,name):self.name=namedef get_unit(self):unit = int(input("请输入商品序号>>>"))return unitdef get_number(self):number = int(input("请输入商品数量>>>"))return numberdef get_total_price(self):unit = self.get_unit()number = self.get_number()total_price = goods[unit][1] * numberret = self.discount(total_price)print("%s于%s总共花费%s元"%(self.name,datetime.datetime.today(),ret))return retdef discount(self,price):return price# bill=Bill("Yuan老师")
# bill.get_total_price()class NationalDayBill(Bill):def discount(self, price):if price > 399:return price-200return super().discount(price)# ndb=NationalDayBill("Yuan")
# ndb.get_total_price()class Double11Bill(Bill):def discount(self,price):if price > 200:free = random.randint(0, 1)if free == 0:return 0return super().discount(price)# mab=Double11Bill("Yuan")
# mab.get_total_price()# 问题:如果再加一个中秋节满五百折扣0.8
# 但是假如中秋节和国庆节是一天,所以两个优惠同时享受的话该怎样设计?class MiddleAutumeBill(NationalDayBill):def discount(self, price):if price > 500:temp_price = super().discount(price)     # 国庆优惠后的价格return temp_price*0.8                    # 中秋再次优惠return super().discount(price)               # 国庆优惠后的价格mab=MiddleAutumeBill("Yuan")
mab.get_total_price()

1.3.5 多重继承

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:

class SubClassName (ParentClass1[, ParentClass2, ...]):...

继承 基类、功能类

继承中查找方法的方法顺序是:先查子类,然后从左往右,从最左边父类找,没有的话再往右边的类找

class Animal:def eat(self):print("eating...")def sleep(self):print("sleep...")# def fly(self):#     print('fly.... from  Animal class')# 功能类
class Fly:def fly(self):print('fly.... from  Fly class')class Eagle(Animal, Fly):passclass Bat(Animal, Fly):passalex = Eagle()
alex.eat()
alex.fly()

1.4 判断类的继承关系:type 和isinstance方法


class Animal:def eat(self):print("eating...")def sleep(self):print("sleep...")class Dog(Animal):def swim(self):print("swimming...")alex = Dog()
mjj = Dog()a = Animal()print(isinstance(alex, Dog))         # True
print(isinstance(alex, Animal))      # True
print(type(alex))              # <class '__main__.Dog'>print(isinstance(a, Dog))      # False# 判断 A 是否 为 B 的子类
print(issubclass(Animal, (Dog,)))     # False
print(issubclass(Dog, (Animal,)))     # True

1.5 查看实例的所有属性:dir()方法和__dict__属性

dir(obj)可以获得对象的所有属性列表, 而obj.__dict__对象的自定义属性字典

注意事项:

  1. dir(obj)获取的属性列表中,方法也认为属性的一种返回的是list
  2. obj.__dict__只能获取自己自定义的属性,系统内置属性无法获取。返回是dict
class Student:def __init__(self, name, score):self.name = nameself.score = scoredef test(self):passyuan = Student("yuan", 100)
print("获取所有的属性列表")
print(dir(yuan))print("获取自定义属性字段")
print(yuan.__dict__)

在这里插入图片描述
其中,类似__xx__的属性和方法都是有特殊用途的。如果调用len()函数视图获取一个对象的长度,其实在len()函数内部会自动去调用该对象的__len__()方法

2、面向对象特性之封装

2.1 封装概述

是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

2.1.1 封装原则

  • 将不需要对外提供的内容都隐藏起来
  • 把属性隐藏,提供公共方法对其访问

2.1.2 封装好处

  1. 隐藏实现细节,提供公共的访问方式
  2. 提高了代码的复用性
  3. 提高安全性

2.2 私有属性

2.2.1 私有属性定义

在class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。但是,从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的namescore属性:

class Student(object):def __init__(self, name, score):self.name = nameself.score = scorealex=Student("alex",66)
yuan=Student("yuan",88)alex.score=100
print(alex.score)

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:

class Student(object):def __init__(self, name, score):self.__name = nameself.__score = scorealex=Student("alex",66)
yuan=Student("yuan",88)print(alex.__score)        #  报错

改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name实例变量.__score

这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。

2.2.2 私有属性完整 demo

class Student:def foo(self):print(self.__score)                     # self.__score  --> self._Student__scoreclass Person(Student):def __init__(self, name, score):self.name = nameself.__score = score                      # self.__score --> self._Person__scoredef get_score(self):print(self.__score)return self.__score                        # self.__score --> self._Person__scoredef set_score(self, score_val):if isinstance(score_val, int) and 0 <= score_val <= 100:self.__score = score_val                # self.__score --> self._Person__scoreelse:raise ValueError('input error value!')alex = Person('alex', 66)
alex.get_score()
# print(alex.__score)     # AttributeError: 'Person' object has no attribute '__score'# print(alex.__dict__)      # 查看实例自定义的属性
# {'name': 'alex', '_Person__score': 66}          #  这块简单转化,设置为私有属性,但也很容易拿,一切靠自觉# 私有化的伪装
# print(alex._Person__score)     # 66# 内部 判断 设置 属性值 的 合理性
alex.set_score(1000)             # ValueError: input error value!# 私有属性  只能在 本类 中使用
alex.foo()    # AttributeError: 'Person' object has no attribute '_Student__score'

2.2.3 私有属性总结

  1. 私有属性 只能在 本类 使用
  2. 确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
  3. 这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名属性名就可以拼出名字:

_类名__属性, 然后就可以访问了,如 alex._Student__score

  1. 变形的过程只在类的内部生效, 在定义后的赋值操作,不会变形

2.3 单下划线、双下划线、头尾双下划线说明

  • __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。

  • _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问。(约定成俗,不限语法)

  • __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

2.4 私有方法

在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的:

class Base:def __foo(self):print("foo from Base")def test(self):self.__foo()                    # self.__foo()  -->  self._Base__foo()class Son(Base):def __foo(self):                    # self.__foo()  -->  self._Son__foo()print("foo from Son")s = Son()
s.test()
# foo from Base

2.5 property属性装饰器

将 方法 通过 属性 句点符的方式 来操作

使用接口函数获取修改数据 和 使用点方法(alex.name = ‘yuan’ 或者print(yuan.name))设置数据相比, 点方法使用更方便,我们有什么方法达到 既能使用点方法,同时又能让点方法直接调用到我们的接口了,答案就是property属性装饰器:(表象就是把方法当成属性来操作)

class Student(object):def __init__(self, name, score, sex):self.__name = nameself.__score = scoreself.__sex = sex# 方法 进行属性 句点符 取值@propertydef name(self):return self.__name# 修改@name.setterdef name(self, name):if len(name) > 1:self.__name = nameelse:print("name的长度必须要大于1个长度")@propertydef score(self):return self.__score@score.setterdef score(self, score):if score > 0 and score < 100:self.__score = scoreelse:print("输入错误!")yuan = Student('alex', 18, 'male')yuan.name = 'eval'        # 调用了score(self, score)函数设置数据print(yuan.name)          # 调用了score(self)函数获取数据yuan.score = 199
print(yuan.score)

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

3、面向对象特性之多态

3.1 多态的使用

多态是指一类事物有多种形态。比如动物有多种形态,人,狗,猫,等等。文件有多种形态:文本文件,可执行文件。总而言之,多态即某类的再分类,再分的每一类就是父类的多种形态的一种

from abc import ABCMeta, abstractmethod              # (抽象方法)class Payment(metaclass=ABCMeta):         # metaclass 元类  metaclass = ABCMeta表示Payment类是一个规范类def __init__(self, name, money):self.money = moneyself.name = name@abstractmethod                       # @abstractmethod表示下面一行中的pay方法是一个必须在子类中实现的方法def pay(self, *args, **kwargs):passclass AliPay(Payment):def pay(self):# 支付宝提供了一个网络上的联系渠道print('%s通过支付宝消费了%s元' % (self.name, self.money))class WeChatPay(Payment):def pay(self):# 微信提供了一个网络上的联系渠道print('%s通过微信消费了%s元' % (self.name, self.money))class Order(object):def account(self, pay_obj):pay_obj.pay()# 第一个订单
pay_obj = WeChatPay("yuan", 100)
# 第二个订单
pay_obj2 = AliPay("alex", 200)order = Order()
order.account(pay_obj)
order.account(pay_obj2)# yuan通过微信消费了100元
# alex通过支付宝消费了200元

在调用order对象的account()方法时,程序并不关心为该方法传入的参数对象pay_obj是谁,只要求此参数对象pay_obj包含pay()方法即可,而调用者传入的参数对象类型pay_obj是子类对象还是其他类对象,Python无所谓!多态性就是相同的消息(函数方法触发)使得不同的类做出不同的响应,这就是典型的类编程中多态性的应用实例。

3.2 多态发生的前提:

  1. 继承:多态一定是发生在子类和父类之间。
  2. 重写:多态子类重写父类方法

3.3 鸭子模型 (动态类语言)

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。

例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为"鸭子"的对象,并调用它的"走"和"叫"方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的"走"和"叫"方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的"走"和"叫"方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。

from abc import ABCMeta, abstractmethod              # (抽象方法)class Payment(metaclass=ABCMeta):         # metaclass 元类  metaclass = ABCMeta表示Payment类是一个规范类def __init__(self, name, money):self.money = moneyself.name = name@abstractmethod                       # @abstractmethod表示下面一行中的pay方法是一个必须在子类中实现的方法def pay(self, *args, **kwargs):passclass AliPay(Payment):def pay(self):# 支付宝提供了一个网络上的联系渠道print('%s通过支付宝消费了%s元' % (self.name, self.money))class WeChatPay(Payment):def pay(self):# 微信提供了一个网络上的联系渠道print('%s通过微信消费了%s元' % (self.name, self.money))class CardPay(object):def __init__(self, name, money):self.money = moneyself.name = name# 呱呱叫:也可以实现别人所拥有的功能def pay(self):print('%s 通过银行卡消费了%s元' %(self.name, self.money))class Order(object):def account(self, pay_obj):pay_obj.pay()# 第一个订单
pay_obj = WeChatPay("yuan", 100)
# 第二个订单
pay_obj2 = AliPay("alex", 200)
# 第三个订单
pay_obj3 = CardPay('eval', 1999)order = Order()
order.account(pay_obj)
order.account(pay_obj2)
order.account(pay_obj3)# yuan通过微信消费了100元
# alex通过支付宝消费了200元
# eval 通过银行卡消费了1999元

上边代码看来:只要他拥有pay()方法,就可以正确的被调用。

// 静态语言
静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。
例如:C++、Java、Delphi、C#等。// 动态语言
动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。
例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。

上面的例子中order.account(pay_obj)中pay_obj不需要类型声明,像java在使用时要定义好类型

order.account(Payment pay_obj)),所以你传入别的类型对象一定报错,但是python因为时动态语言所以传入的对象只要拥有调用的方法即可视为Payment类型对象,即所谓的鸭子类型

4、魔法方法

4.1 __new__ () 构造方法

Base() 的执行过程:

  1. obj = super().new(cls) : 开辟空间对象 obj, 返回对象 return obj
  2. _init_(obj)

class Base(object):def __new__(cls, *args, **kwargs):"""构造方法:param args::param kwargs::return: obj"""print("我是用来开辟一块空间的")obj = super().__new__(cls)return objdef __init__(self):super().__init__()print('sef 就是__new__() 开辟的空间地址')b = Base()"""
Base() 的执行过程:
1 obj = super().__new__(cls)  : 开辟空间对象 obj  return obj
2 __init__(obj)      
"""# 我是用来开辟一块空间的
# sef 就是__new__() 开辟的空间地址

应用:比如单例模式

4.2 __init__() 初始化方法

#  初始化方法:__init__
class A(object):def __init__(self):print("初始化执行方法")
A()

4.3 __str__()

#  __str__class C(object):def __init__(self,name,age):self.name=nameself.age=agedef __str__(self):         # 必须返回字符串类型return self.namec1=C("c1",20)
c2=C("c2",23)
print(c1)
print(c2)

4.4 __call__()

实例方法都有 __call__方法,实例对象() 一定会走到类的__call__()

#  __call__
class D(object):def __call__(self, *args, **kwargs):print("call 被调用...")print(callable(D))
d1=D()
print(callable(d1))
d1()       #  实例方法都有 __call__方法,实例对象()  一定会走到类的__call__()
  1. python 可调用对象:可以通过内置函数callable来判断,如:
print(callable\(p\))      #True
  1. 如果类定义了__call__方法,那么它的实例可以变为可调用对象

4.5 __del__() 构析方法

class F(object):def __del__(self): print("删除对象时被调用!")         # 当程序运行完成后,python解释器会自动清理f=F()
# del f # 思考:注释掉为什么也会调用__del__? 答案:python解决器自动调用的
import time
time.sleep(100)
  • 应用:文件自动关闭、数据库自动关闭等
class Filehandler(object):file="a.text"def __init__(self):self.f=open(self.file)def __del__(self):self.f.close()

4.6 __getitem__() 字典化操作 属性

class G(object):def __init__(self):passdef __getitem__(self,item):print("__getitem__被调用")def __setitem__(self, key, value):print("__setitem__被调用")def __delitem__(self, key):print("__delitem__被调用")g=G()
g["name"]="alex"
print(g["name"])
del g["name"]

4.7 __getattr__() attr 句点符 操作属性

class H(object):def __init__(self):passdef __getattr__(self, item):print("__getattr__被调用")def __setattr__(self, key, value):print("__setattr__被调用")def __delattr__(self, item):print("__delattr__被调用")h=H()
h.name="alex"
print(h.name)
del h.name

4.8 __eq__() 用于两个对象比较

class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef __eq__(self, other):# if self.name == other.name and self.age == other.age:#     return True# else:#     return Falsereturn Truei1 = Person("alex", 30)
i2 = Person("yuan", 30)
print(i1 == i2)      # True

注意:为了节省内存,实例方法 是 存储在 类空间内,所有 同类下的所有 实例方法 都相等

  • 面试题
class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef foo(self, other):passdef bar(self):passdef __eq__(self, other):print('假定都是True')return True# return self == valuealex = Person("alex", 30)
yuan = Person("yuan", 30)
print(id(yuan.foo) == id(alex.foo))        # True , 所有实例对象方法  都存在 类空间内
print(yuan.foo == alex.bar)                # False, 不同实例方法未调用__eq__方法,肯定是 False
print(yuan.foo == alex.foo)                # True, 相同实例方法调用且修改了__eq__方法,均返回 True
print(yuan.foo == yuan.foo)                # True

实例方法都存在类空间,故id(实例方法)都相同,但对象各异,所以对象.方法 也都不同

class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef foo(self, other):passdef bar(self):passdef __eq__(self, other):print('假定都是True')return True# return self == valuealex = Person("alex", 30)
yuan = Person("yuan", 30)
print(id(yuan.foo) == id(alex.foo))     # True
print(yuan.foo == alex.foo )            # False

4.9 __len__()

class G(object):def __len__(self):return 100g = G()
print(len(g))
print(g.__len__())
# 100
# 100

5、反射

反射这个术语在很多语言中都存在,并且存在大量的运用,今天我们说说什么是反射,反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力,在python中一切皆对象(类,实例,模块等等都是对象),那么我们就可以通过反射的形式操作对象相关的属性。

Python中的反射主要有下面几个方法:

1.hasattr(object,name)

判断对象中有没有一个name字符串对应的方法或属性

2.getattr(object, name, default=None)

获取对象name字符串属性的值,如果不存在返回default的值

3.setattr(object, key, value)

设置对象的key属性为value值,等同于object.key = value

4.delattr(object, name)

删除对象的name字符串属性

应用1:


class Person:def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = genderyuan = Person("yuan", 22, "male")
print(yuan.name)
print(yuan.age)
print(yuan.gender)# getattr  取值
print(getattr(yuan, 'name', 'default_val'))
print(getattr(yuan, 'xxx', 'default_val'))# hasattr  判断是否拥有此属性,返回布尔值
print(hasattr(yuan, 'names'))    # False
print(hasattr(yuan, 'name'))     # True# setattr   修改 对象的 属性 值
print(yuan.name)                    # yuan
setattr(yuan, 'name', 'alex')       # 修改 name 属性值
print(yuan.name)                    # alexwhile 1:attr = input('请输入属性名>>>')if hasattr(yuan, attr):val = getattr(yuan, attr)print(val)else:print('没有该属性!')val = input('请为该属性赋值>>>')setattr(yuan, attr, val)

应用2: FTP

class FTP(object):def __init__(self):self.run()def run(self):print('''提示:上传:   put 路径/文件名称下载:   get 路径/文件名称''')while 1:input_str=input(">>>")action, params = input_str.split(" ")if hasattr(self, action):getattr(self, action)()else:print("不存在该方法")def put(self):print("上传...")def get(self):print("下载...")ftp = FTP()

这篇关于py面向对象特性:继承、封装、多态、鸭子模型、魔法方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/724015

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

图神经网络模型介绍(1)

我们将图神经网络分为基于谱域的模型和基于空域的模型,并按照发展顺序详解每个类别中的重要模型。 1.1基于谱域的图神经网络         谱域上的图卷积在图学习迈向深度学习的发展历程中起到了关键的作用。本节主要介绍三个具有代表性的谱域图神经网络:谱图卷积网络、切比雪夫网络和图卷积网络。 (1)谱图卷积网络 卷积定理:函数卷积的傅里叶变换是函数傅里叶变换的乘积,即F{f*g}

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费