【Python学习004】Pythonic代码风格(一)

59 阅读3分钟

【Python学习004】Pythonic代码风格(一)

大家好,我们的gzh是朝阳三只大明白,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),跪求一波关注,希望和大家一起努力、进步!!

命名

命名的核心目的在于让其他开发者在不了解细节的情况下依旧能读懂代码,符合一定命名规范的代码具有更好的可读性。

命名风格

snake_case

多个单词之间使用下划线进行分割,所有的单词都是小写,具体示例如下:

def is_valid():
	...

def get_col_cnt():
	...

def is_minimized():
	...

camelCase

词和词之间没有分割符,首个词小写,其他单词都是大写,示例如下:

def isValid():
	...
	
def getColCnt():
	...

def isMinimized():
	...

PascalCase

词和词之间没有分割符,所有的单词首字母大写,示例如下:

class AdminRole:
	...

class Admin:
	...

class StreamGraph:
	...

命名的基本要求

  • 值或者对象:使用简短的名词搭配形容词;
  • 函数或者方法:使用动词搭配形容词;
  • 类:使用简短的名词组合。

命名变量、常量和属性

命名常量、变量和属性一般采用【名词+形容词】的组合,具体示例如下:

  • 命名一个对象:通常采用snake_case 方式进行命名,例如 authorized_usersql_database
  • 命名一个数值类型或者字符串:通常采用snake_case 方式进行命名,添加形容词或者名词添加更多描述信息,例如 full_namefirst_nameage
  • 命名一个布尔类型:通常采用snake_case 方式进行命名,通常以has开头,例如 has_activehas_minimizedhas_foucus

命名函数或者方法

命名一个函数或者方法,通常以一个动词开头,对于表现一个行为的函数或者方法,命名应当描述那一次操作的目的,示例如下:

def get_active_user(...):
	...

def append_data(...):
	...

def get_user_by_email(...):
	...

对于返回值是布尔类型的方法或函数,应当以is开头的疑问形式命名,示例如下:

def is_email_valid():
	...

def is_empty():
	...

def is_fullscreen():
	...

命名类

命名类一般采用 PascalCase 格式命名,类的命名应当反应其所表现的抽象,其示例如下:

class Customer:
	...

class User:
	...

class Admin:
	...

小结

根据上述原则,我个人推荐的规则如下:

Type命名约定例子
Function使用小写单词、下划线分割function, a_function
method使用小写单词、下划线分割method, a_method
Variable使用小写单词、下划线分割hero, shopping_cart
Constant使用大写单词、下划线分割MAX_SIZE, LEVEL
ClassPascalCase 写法 ,首字母大写Order,UserOrder
Module使用小写单词、下划线分割user_order.py
Package简短的小写单词,不要使用下划线user

合理的结构

合理的类结构

class ClassName:
    # 类变量
    DEFAULT_TITLE: AnyStr = 'title'
    ...
    
    # init方法 
    def __init__(self, ...):
        pass
    
    # 魔术方法
    def __repr__(self, ...):
        pass
    
    # 类方法
    @classmethod
    def method(...):
        pass
    
    # 静态方法
    @staticmethod
    def method(...):
		pass
    
    # 私有方法
    def __method(self, ...):
        pass
    
    # getter、setter方法
    @property
    def method(self):
        ...
    
    # 实例方法
    def method(self, ...):
        pass

合理的 try-catch 结构

import traceback
try:
	f()
except ValueError:
    ...
    
except NameError:
    ...   
    
except Exception as e:
    print(e)
    trackback.print_exc()
    
else:
    # 无错误的处理方式 
finally:
    ...

示例

Sidebar 示例

class SideBar:  
    DIV: str = 'div'  
    H1: str = 'h1'  
    MORE: str = 'more'  
    MORE_ITEMS_LENGTH: int = 3  
    SHOULD_COMPRESS_HTML: bool = True  
  
    def __init__(  
            self,  
            title: str,  
            menu_items: [str],  
            more: str = MORE,  
            more_items_length: int = MORE_ITEMS_LENGTH,  
            should_compress_html: bool = SHOULD_COMPRESS_HTML  
    ) -> None:  
        self.title = title  
        self.more = more  
        self.more_items_length = more_items_length  
        self.should_compress_html = should_compress_html  
        self.menu_items = menu_items  
  
    def __len__(self):  
        return len(self.menu_items)  
  
    def __repr__(self):  
        return f'SideBar: {len(self)} menu items'  
    @classmethod  
    def _header(cls, title):  
        return cls._build_header(cls.H1, title)  
  
    @classmethod  
    def _body(cls, menu_items: [str], should_compress_html: bool) -> str:  
        split_char = cls._get_split_char(should_compress_html)  
        return split_char.join(  
            list(cls._build_body(cls.DIV, menu_items))  
        )  
  
    @classmethod  
    def _more(cls, more):  
        return cls._build_more(cls.DIV, more)  
  
    @staticmethod  
    def _build_header(tag_name: str, title: str) -> str:  
        return f'<{tag_name}>{title}</{tag_name}>'  
  
    @staticmethod  
    def _build_body(tag_name: str, menu_items: [str]) -> str:  
        for menu_item in menu_items:  
            yield f'<{tag_name}>{menu_item}</{tag_name}>'  
  
    @staticmethod  
    def _build_more(tag_name: str, text: str) -> str:  
        return f'<{tag_name}>{text}</{tag_name}>'  
  
    @staticmethod  
    def _get_split_char(should_compress_html: bool) -> str:  
        return '' if should_compress_html else '\n'  
  
    def _is_few_items(self):  
        return len(self) < self.more_items_length  
  
    def build(self) -> str:  
        header = self._header(self.title)  
        body = self._body(self.menu_items, self.should_compress_html)  
        footer = self._more(self.more) if self._is_few_items() else ''  
        split_char = self._get_split_char(self.should_compress_html)  
        html = split_char.join([header, body, footer])  
        return html  
  
  
if __name__ == '__main__':  
    side_bar = SideBar(  
        'DEMO SIDE BAR',  
        ['a', 'b', 'c'],  
        should_compress_html=False,  
        more_items_length=3  
    )  
    print(side_bar.build())

往期回顾

  1. 【Python学习003】高效数据结构-列表
  2. 【Python学习002】函数参数

文中难免会出现一些描述不当之处(尽管我已反复检查多次),欢迎在留言区指正,相关的知识点也可进行分享,希望大家都能有所收获!!