python 类与对象

其他语言有的和不太重要的大概不写了

方法没有重载

由于python方法的参数没有类型,参数的数量也是可以由可变参数控制,因此python中没有方法的重载。

如果在一个类中定义多个重名的方法,只有最后一个方法有效。

eg

class Person:
    def say_hi(self): # 这个方法被下面的同名方法覆盖了
        pass
        
    def say_hi(self, name): # 只有这一个有效
        print("{0},hello",format(name))

方法的动态性

一切皆为对象

class Person:
    def saying(self):
        print('waring up')

def play_game(s):
    print("{0} are playing game".format(s))

def saying(s):
    print('114514')

p = Person()

try:    
    p.play()
except AttributeError:
    print('have no such method')

Person.play = play_game # 虽然Person类内没有方法play,但可以通过引用的方式绑定方法

p.saying()

Person.saying = saying # 同上

p.saying()

p.play()

image

封装

python对于类成员没有严格的访问控制限制。

关于私有属性和方法:

1.通常我们约定,双下划线开头的属性是私有的。

2.类内部可以访问私有属性(方法)

3.类外部不能直接访问私有方法

4.类外部可以通过'_类名__属性名'进行访问
(双下划线开头之后是以这样的命名格式存的)

class Person:
    def __init__(self, a):
        self.now_gcd = a

    # 内部方法相互调用时需要加self
    def __gcd(self, a, b): # 私有方法gcd
        if b != 0:
            return self.__gcd(b, a%b)
        else:
            return a

    def make_gcd(self,a):
        self.now_gcd = self.__gcd(self.now_gcd, a)
        return self.now_gcd


now = Person(114514)

try:
    now.__gcd(now.now_gcd, 1919810)
except(AttributeError):
    print('NO such Attribute')

print(now.make_gcd(1919810))

image

装饰器@property

@property装饰器作用是:将方法变成属性调用。

class Person:
    def __init__(self, a):
        self.__num = a
    
    # 读取num
    @property # 实现一个num相关的getter方法
    def num(self):
        print('now num is ',self.__num)
    
    # 设置num
    @num.setter
    def num(self, a):
        if 1000<=a<=10000:
            self.__num = a
        else:
            print('Value range Error')

A = Person(114514)

A.num # 类Person中num是私有属性,但存在num的getter方法,通过@property将方法变成属性调用

A.num = 2000

A.num

A.num = 114514

try:
    A.num() # 变成属性后调用方法会报错
except(TypeError):
    print('int object is not callable')

image

如果未实现setter,则该属性为只读属性

继承

python支持多重继承,一般情况尽量避免使用:
image

class classname(fa_class1, fa_class2, ......):

MRO(Method Resolution Order):方法解析顺序

对于父类同名方法,对于括号内的父类从左向右扫描以第一个出现的方法为准。

image

如果没有指定父类,则默认父类为object,即object是所有类的父类,所有类共同拥有一些默认实现,例如:__new__()

定义子类时,必须(语法上不强制)在其构造函数中调用父类的构造函数:

父类名.__init__(self,参数列表)
'''
也可以直接在子类的构造函数中对父类属性赋值,不过这样不能体现继承的
优势,因为子类继承了父类的构造函数(子类有自己的构造函数)
'''

方法可以重写,子类的同名方法会覆盖继承的父类方法。

多态

多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。
多态的注意事项:
1.多态是方法的多态,属性没有多态;
2.多态的存在有两个必要条件:继承、方法重写。

class Man:
	def eat(self):
		print('吔饭啦')

class Chinese(Man):
	def eat(self):
		print('eat by chopsticks')

class LiangFeifan(Man):
	def eat(self):
		print('吔*')
		
def manEat(m):
	if isinstance(m,Man):
		m.eat()
	else:
		print("it's no a man")

manEat(Chinese())
manEat(LiangFeifan())

image

重写__str__方法

class Person: # 默认继承object
    def __init__(self, name):
        self.__name = name
    def __str__(self):
        return 'This is a personal __str__'
p = Person('tshe')
print(p)

image

重载

都是对象,都可以重载

image
image

特殊属性

class Man:
	def eat(self):
		print('吔饭啦')

class Chinese(Man):
	def eat(self):
		print('eat by chopsticks')

class LiangFeifan(Chinese, Man):
    def __init__(self,name):
        self.name = name
    
    def eat(self):
	    print('吔*')

L = LiangFeifan('lff')

print(dir(L))
print(L.__dict__)
print(L.__class__)
print(LiangFeifan.__bases__)
print(LiangFeifan.mro())
print(Man.__subclasses__)

image

浅复制和深复制

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。(浅复制时两个对象指向同一地址,深复制时给对象复制了新的内存,并复制了相同的值)

posted @ 2021-08-12 10:14  Lecoww  阅读(105)  评论(0)    收藏  举报